如何解决.then优先于Promise之外的代码?
假设我们在异步函数中有一个承诺:
(async function() {
let x = 0;
await new Promise((resolve,reject) => {
setTimeout(() => resolve(),2000)
})
.then(res => {
x = 100;
})
console.log(x);
})();
控制台输出始终为100
,从不为0
。我在所有主流浏览器和Node.js中都尝试过。这正是我想要看到的,但是我感觉到周围有代码的味道。我不确定这是否是将值传递给x
的安全方法。即使我在上面放了很多代码,它也似乎可以工作。除非它是异步的(例如另一个setTimeout()
),否则一切都很好。
有人可以确认.then()
分支是否真的优先并且在alert(x)
行之前运行,还是仅是偶然发生?
(是的,我知道有更好的方法可以做到这一点,但这是一个简化的概念验证代码段。)
解决方法
这是可以保证的,因为await
会阻塞,直到承诺链完成为止。这是因为链接到原始承诺的.then
返回了一个 new 承诺,而await
对此进行了操作。
预期的行为是,在x已经被分配之后(作为诺言链的一部分),console.log从函数开始运行(解决诺言时)开始出现约2秒钟。
对于“代码异味”-我认为从承诺中返回状态并避免副作用是更清洁的方法。但是,由于范围有限且执行顺序有保证。.
,是的,此方法是“安全的”。您明确地await
返回.then()代码块的承诺。如果您的Promise拒绝了(例如,失败的网络请求),则您的代码将中断,因此请确保在末尾添加.catch(error)。
顺便说一句,编写此代码的一种更简洁的方式是这样的:
(async function() {
let x = 0;
await new Promise((resolve,reject) => {
setTimeout(() => resolve(),2000)
});
x = 100;
console.log(x);
})();
如果您不需要Promise的返回值,则此代码的行为与您的代码完全相同。
编辑: 由于Promise应该确实提供了值,因此您可以将其重写为:
(async function() {
let x = 0;
const res = await new Promise((resolve,reject) => {
setTimeout(() => resolve(100),2000)
});
x = res;
console.log(x);
})();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。