Tob*_*ühl 16 javascript promise ecmascript-6 bluebird es6-promise
我有一个返回数据的承诺,我希望将其保存在变量中.这在JavaScript中是不可能的,因为异步性质,我需要onResolve用作回调吗?
我可以以某种方式使用它(例如用async/await包装):
const { foo, bar } = Promise.then(result => result.data, errorHandler);
// rest of script
Run Code Online (Sandbox Code Playgroud)
而不是这个?
Promise.then(result => {
const { foo, bar } = result.data;
// rest of script
}, errorHandler);
Run Code Online (Sandbox Code Playgroud)
注意:使用Bluebird库而不是本机实现,我无法从Promise更改为asnyc/await或Generators.
sil*_*min 23
不,你不能像你在你的例子中建议的那样同步地获取数据.必须在回调函数中使用该数据.或者在函数式编程风格中,可以对promise数据进行map()编辑.
如果您可以使用async/await(它应该很棒),那么您可以编写看起来同步但保留promise的异步性的代码(请参阅@loganfsmyth注释).
const { foo, bar } = await iAmAPromise.then(result => result.data);
Run Code Online (Sandbox Code Playgroud)
总的来说,因为你已经在使用ES6,我假设你也在使用一个转换器.在这种情况下你绝对应该尝试async/await.请务必在决定权重,因为今天他们还没有批准的规范.
虽然您可以从异步函数内的等待的Promise中获取值(仅仅是因为它暂停了该函数以等待结果),但您永远无法直接从Promise中获取值并返回到与Promise本身相同的作用域中。
这是因为“超出”意味着尝试获取将来存在的某些东西(最终解析的值)并将其放入过去已经发生的上下文(同步变量赋值)中。
也就是说,时间旅行。即使时间旅行是可能的,但这也不是一个好的编码习惯,因为时间旅行可能会非常混乱。
通常,如果您觉得自己需要这样做,则表明您需要重构某些东西,这是一个好兆头。请注意,您在此处使用“结果=> result.data”的操作:
Promise.then(result => result.data, errorHandler);
// rest of script
Run Code Online (Sandbox Code Playgroud)
您已经通过将...传递给函数来使用.. (实际上是映射)该值。但是,假设“ //脚本的其余部分”做了一些与此值相关的重要事情,您可能想继续使用另一个函数映射到现在更新的值上,然后再对该值做一些副作用(例如显示屏幕上的数据)。
Promise
.then(result => result.data)
.then(data => doSomethingWithData)// rest of script
.catch(errorHandler);
Run Code Online (Sandbox Code Playgroud)
将来会在某个未知点调用“ doSomethingWithData”(如果曾经被调用过)。这就是为什么最好将所有行为明确封装到特定功能中,然后将该功能挂接到Promise链上的原因。
说实话,这是更好的方法,因为它要求您明确声明将要发生的特定事件序列,并与所有应用程序代码执行的第一次运行明确地分开。
换句话说,假设此场景假设在全局顶级范围内执行:
const { foo, bar } = Promise.then(result => result.data, errorHandler);
console.log(foo);
//...more program
Run Code Online (Sandbox Code Playgroud)
您希望在那里发生什么?有两种可能性,并且两者都是不好的。