Promise 中多个请求同时触发时如何处理

在前端开发中,经常需要同时请求多个接口或者同时处理多个任务。而 Promise 是一种非常常用的异步编程方式,可以方便地处理这种情况。本文将详细介绍 Promise 中多个请求同时触发时的处理方法。

问题

假设现在有多个异步请求,需要同时触发。例如,我们需要请求三个不同接口的数据,然后对这三个接口的数据进行合并和处理。对于这种情况,我们应该如何处理?

解决方案

Promise.all

Promise 提供了一个 all 方法,在多个异步操作并行执行后,将所有的操作结果放在一个数组中返回。这个方法接收一个 Promise 实例数组作为参数,如下所示:

Promise.all([p1, p2, p3])
  .then(results => {
    // results 包含所有 Promise 实例的返回结果
  })
  .catch(error => {
    // 处理错误
  });

下面我们通过一个示例来看看 Promise.all 是如何处理上述场景的:

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

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve({ age: 18 });
  }, 2000);
});

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

Promise.all([promise1, promise2, promise3]).then(results => {
  const [result1, result2, result3] = results;
  const user = { ...result1, ...result2, ...result3 };
  console.log(user); // { name: 'Alice', age: 18, gender: 'female' }
});

在这个示例中,我们分别创建了三个 Promise 实例,分别表示三个接口的数据请求。然后使用 Promise.all 将它们组合起来,并在得到三个接口的数据之后,合并它们并打印到控制台中。

Promise.race

除了 all 方法以外,Promise 还提供了 race 方法。这个方法同样接收一个 Promise 实例数组作为参数,但是当其中任意一个 Promise 实例完成时,就会返回这个 Promise 实例的结果。例如:

var p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p1');
  }, 1000);
});

var p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('p2');
  }, 2000);
});

Promise.race([p1, p2]).then(result => {
  console.log(result); // 'p1'
});

这个示例中,我们创建了两个 Promise 实例,分别在 1 秒和 2 秒后完成。使用 Promise.race 方法,最终结果将是 p1 的结果。

async 和 await

除了 Promise 的 all 和 race 方法以外,我们还可以使用 async 和 await 来简化异步操作。

通过在函数前添加 async 关键字,我们声明了这是一个异步函数。在异步函数中,我们最好采用 try-catch 语句来捕获异常,避免程序崩溃。

await 关键字可以把异步操作变成同步的写法,使得代码更容易阅读和维护。例如:

async function getUser() {
  try {
    const result1 = await fetch('/api/user');
    const result2 = await fetch('/api/info');
    const result3 = await fetch('/api/task');
    const json1 = await result1.json();
    const json2 = await result2.json();
    const json3 = await result3.json();
    const user = { ...json1, ...json2, ...json3 };
    return user;
  } catch (error) {
    // 处理错误
  }
}

getUser().then(user => {
  console.log(user); // 合并后的用户数据
});

在这个示例中,我们声明了一个名为 getUser 的异步函数,在这个函数中,我们使用 await 关键字来阻塞代码,直到得到一个正确的返回结果。之后,我们把得到的三个 JSON 数据合并为一个 user 对象,并返回结果。

总结

本文讨论了 Promise 中多个请求同时触发时的处理方法,介绍了 Promise 的 all 和 race 方法,以及使用 async 和 await 简化异步操作的方法。在使用 Promise 时,我们要注意动态处理 Promise 数组,避免因 Promise 数组长度变化而引起的错误。同时,我们也要注意 catch 中的错误处理,避免因异步操作出错导致程序崩溃。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a475ccadd4f0e0ffcbc833


纠错反馈