发布于 2026-01-06 1 阅读
0

关于处理 Promise,你需要了解的所有(或大部分)内容

关于处理 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 KarataevJoel 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 还不支持此功能。
文章来源:https://dev.to/orivolfo/all-or-just-most-of-what-you-need-to-know-about-handling-promises-59eh