关于处理 Promise,你需要了解的所有(或大部分)内容
我并不每天都用到 Promise。但当我需要用到它时,我只需要一个简单的使用示例。然而,我找到的却是过于复杂的示例,以及大量关于异步编程和JavaScript 中 Promise理论
的文章。 最终,我不得不花几分钟重新学习 Promise,才意识到在大多数情况下,我实际处理 Promise 的方式只有两三种。
因此,我创建了一个名为“Promise Sandbox”的 GitHub 仓库,其中包含了我需要的三个主要用法,并确保代码尽可能简洁。
在这个例子中,我只执行了两个 Promise:一个较长的,一个较短的。
你可以添加更多 Promise,但这只会使代码更长更复杂,而不会给你带来任何新的见解。
让我们直接进入代码部分!
承诺执行
这里我执行了两个简单的 Promise。目前设置为 resolve(如果您希望它们被 reject,可以反转注解)。longPromise
设置为 10 秒后 resolve。shortPromise
设置为 2 秒后 resolve。
var longPromise = ()=>{
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('longPromise resolved');
// reject('longPromise rejected');
}, 10000);
})
};
var shortPromise = ()=> {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('shortPromise resolved');
// reject('shortPromise rejected');
}, 2000);
})
};
处理选项
经典链式
这是处理 Promise 的传统方法。但这很
容易让你陷入回调地狱。
longPromise()
.then((data)=>{
console.log(data); // logs: longPromise resolved
shortPromise()
.then((data)=>{
console.log(data) // logs: shortPromise resolved
})
.catch((data)=>{
console.log(data) // logs: shortPromise rejected
})
.catch((data)=>{
console.log(data) // logs: longPromise rejected
// shortPromise is unhandled in case longPromise was rejected
});
});
已编辑:
正如博主Eugene Karataev和Joel Ruiz所建议的那样,我们可以通过返回以下 Promise 对象而不是直接调用它来避免回调地狱。
这将简化嵌套结构,使代码更易读:
longPromise()
.then((data)=> {
console.log(data); // logs: longPromise resolved
return shortPromise();
})
.then((data)=>{
console.log(data) // logs: shortPromise resolved
})
.catch((error)=> {
console.log(error); // One catch to reject them all!
});
承诺一切
将所有 Promise 批量放入一个数组中,一次性处理。
如果您使用的是Node.js,我建议您JSON.stringify记录数据。
Promise.all([longPromise(), shortPromise()]).then(function(data) {
console.log(data);
});
异步等待(感谢 ES6!)
更准确地说,应该是 ES8。
如果你不想处理 JavaScript 的异步特性,那就让新的async/await功能来处理吧。确保将await语句包裹在一个异步函数中。
在这个例子中,我把异步函数写成了立即执行函数表达式(IIFE),以确保它能立即执行。
(async ()=>{
let long = await longPromise();
let short = await shortPromise();
console.log(long); // logs: longPromise resolved
console.log(short); // logs: shortPromise resolved
})();
这在任何浏览器上都应该能正常运行(IE 除外。IE 不是浏览器!)。
其余未提及的部分
- 如果你不关心 Promise 是被解决还是被拒绝,那么在处理单个 Promise 时,请使用 ` and/or`
.finally()而不是`and/or` 。.then().catch() - 此外,
Promise.all()你还有Promise.race()类似的东西Promise.all(),但会在第一个承诺完成后调用。 - 还有一项
Promise.allSettled()功能,目前仍处于发展阶段,大多数浏览器和低于 12.9 版本的 Node 还不支持此功能。