我有一个承诺,返回数据,我想将其保存在变量中。这在JavaScript中是不可能的,因为异步性质,我需要使用 onResolve
作为回调?
我可以以某种方式使用它(例如用async / await包装):
const { foo, bar } = Promise.then(result => result.data, errorHandler);
// rest of script
而不是这个?
Promise.then(result => {
const { foo, bar } = result.data;
// rest of script
}, errorHandler);
注意:使用Bluebird库而不是本机实现,我无法从Promise更改为asnyc / await或Generators。
不,你无法获得数据 同步 出于你在你的例子中建议的承诺。数据必须在回调函数中使用。或者在函数式编程风格中,promise数据可以是 map()编辑。
如果你可以使用 异步/ AWAIT (你应该这很棒)然后你可以编写看起来同步的代码但保留promise的异步性(参见@loganfsmyth comments)。
const { foo, bar } = await iAmAPromise.then(result => result.data);
总的来说,因为你已经在使用ES6,我假设你也在使用一个转换器。在这种情况下,你一定要给 异步/ AWAIT 一试。
请务必在决定中重视,因为今天他们还没有批准的规范。
虽然你可以在async函数中从一个等待的Promise中获取一个值(只是因为它暂停了等待结果的函数),但是你不能直接从Promise中获取一个值并返回到与Promise本身相同的范围内。 。
那是因为“out of”意味着尝试采取未来存在的东西(最终解决的值)并将其置于上下文(同步变量赋值)中 已经发生在过去。
也就是时间旅行。即使时间旅行是可能的,也可能不是一个好的编码实践,因为时间旅行可能会非常混乱。:)
一般来说,如果你发现自己感觉需要这样做,那么你需要重构某些东西是个好兆头。请注意你在这里使用“result => result.data”做的事情:
Promise.then(result => result.data, errorHandler);
// rest of script
..是 已经 您通过将值传递给函数来处理(字面上,映射)值的情况。但是,假设“//脚本的其余部分”执行与此值相关的重要事项,您可能希望这样做 继续 使用另一个函数映射现在更新的值,然后使用该值执行side-effect-y(如在屏幕上显示数据)。
Promise
.then(result => result.data)
.then(data => doSomethingWithData)// rest of script
.catch(errorHandler);
将调用“doSomethingWithData”(如果 它曾被称为未来某个未知点。这就是为什么将所有行为清楚地封装到特定函数中然后将该函数挂钩到Promise链是一个好习惯。
老实说,这样做更好,因为它要求你清楚地声明一个特定的事件序列 将 发生,明确地从第一次运行中分离出所有应用程序代码的执行。
换句话说,想象一下这个场景,假设在全局顶级范围内执行:
const { foo, bar } = Promise.then(result => result.data, errorHandler);
console.log(foo);
//...more program
你期望在那里发生什么?有两种可能性,它们都很糟糕。
- 你的整个程序(console.log以及之后发生的一切)
它会 有 停止并等待Promise执行
在它知道“foo”会是什么之前......不, 威力 是。 (这是
异步函数中的“await”实际上是做什么的:它暂停了
整个函数,直到值或错误返回)
- foo和bar只是未定义(这实际上就是这样
发生),因为,同步执行,他们只是
Promise对象不存在的属性(不是值,
但是Monad包含最终值或错误)
可能甚至没有包含值。