JS 使用Promise 多个异步方法实现结果同步组合

209 阅读3分钟

简介

Promise 是 JavaScript 中用于处理异步操作的一种机制。它表示一个异步操作的最终完成或失败,以及完成时的返回值或失败原因。Promise 可以被看作是一种状态机,它有三种状态:

  • Pending(进行中):初始状态,表示异步操作还未完成。
  • Fulfilled(已成功):表示异步操作已经成功完成,并且有一个返回值。
  • Rejected(已失败):表示异步操作已经失败,并且有一个失败原因。

一旦 Promise 进入 Fulfilled 或 Rejected 状态,它就变成了不可变的,这意味着它的状态不会再改变。

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。resolve 函数用于将 Promise 的状态从 Pending 变为 Fulfilled,并将异步操作的结果作为参数传递给 then 方法;而 reject 函数用于将 Promise 的状态从 Pending 变为 Rejected,并将错误原因作为参数传递给 catch 方法。

Promise 的 then 方法和 catch 方法可以用于处理 Fulfilled 和 Rejected 状态的 Promise。then 方法接受两个参数,第一个参数是处理 Fulfilled 状态的回调函数,第二个参数是处理 Rejected 状态的回调函数。catch 方法只接受一个参数,处理 Rejected 状态的回调函数。

Promise 还提供了一些静态方法,例如 Promise.all()、Promise.race() 等,用于处理多个 Promise 对象的状态。

下面是一个使用 Promise 的示例:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber > 0.5) {
      resolve(randomNumber);
    } else {
      reject('Failed');
    }
  }, 1000);
});

promise.then(result => {
  console.log(`Success: ${result}`);
}).catch(error => {
  console.log(`Error: ${error}`);
});

在上面的示例中,我们创建了一个 Promise 对象,并在其中模拟了一个异步操作,在 1 秒后随机返回一个数字。如果返回的数字大于 0.5,则将 Promise 状态从 Pending 变为 Fulfilled,并将数字作为参数传递给 then 方法;否则将 Promise 状态从 Pending 变为 Rejected,并将字符串 'Failed' 作为参数传递给 catch 方法。在 then 方法和 catch 方法中分别处理 Fulfilled 和 Rejected 状态的 Promise。

多个异步方法实现同步组合方法如下

方法1、使用 Promise.all() 方法可以将多个 Promise 对象组合成一个 Promise 对象,等待所有 Promise 对象都完成后再返回结果。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 1');
  }, 1000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 2');
  }, 2000);
});

const promise3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Promise 3');
  }, 3000);
});

Promise.all([promise1, promise2, promise3])
  .then(results => {
    console.log(results); // ['Promise 1', 'Promise 2', 'Promise 3']
  });

方法2、使用 async/await 可以让异步代码看起来像同步代码。

async function myFunction() {
  const result1 = await promise1();
  const result2 = await promise2();
  const result3 = await promise3();
  console.log([result1, result2, result3]); // ['Promise 1', 'Promise 2', 'Promise 3']
}

myFunction();

方法3、使用回调函数可以在一个异步函数完成后执行另一个异步函数。

function myFunction(callback) {
  promise1().then(result1 => {
    promise2().then(result2 => {
      promise3().then(result3 => {
        callback([result1, result2, result3]);
      });
    });
  });
}

myFunction(results => {
  console.log(results); // ['Promise 1', 'Promise 2', 'Promise 3']
});
注意,使用回调函数嵌套会造成回调地狱,代码难以维护,因此建议尽可能使用 Promise 或 async/await 来实现同步组合。