使用async,await解决一个页面调用多个接口顺序的问题

456 阅读3分钟

在开发需求中,一个页面初始化会遇到多个接口调用,他们相互依赖,并且b接口依赖a接口的底层处理以及数据.这个时候,就可以使用async 和 await.

在 JavaScript 中,async 和 await 是用于处理异步操作的语法糖,使代码看起来更像同步代码。通过使用 async 函数和 await 关键字,你可以更容易地处理多个异步操作。以下是一些示例,展示如何在不同场景下使用多个 async 和 await

基本示例

假设我们有三个异步函数,它们分别返回不同的数据:

async function fetchData1() {  
 return new Promise((resolve) => {  
    setTimeout(() => {  
     console.log("Data 1 fetched");  
     resolve("Data 1");  
   }, 1000);  
 });  
}  
  
async function fetchData2() {  
 return new Promise((resolve) => {  
    setTimeout(() => {  
     console.log("Data 2 fetched");  
     resolve("Data 2");  
   }, 2000);  
  });  
}  
  
async function fetchData3() {  
   return new Promise((resolve) => {  
     setTimeout(() => {  
       console.log("Data 3 fetched");  
       resolve("Data 3");  
      }, 3000);  
   });  
}  

顺序执行多个异步操作

如果你希望顺序执行多个异步操作,可以使用 await 依次等待每个操作完成:

async function fetchSequentially() {  
const data1 = await fetchData1();  
console.log(data1);  
  
const data2 = await fetchData2();  
console.log(data2);  
  
const data3 = await fetchData3();  
console.log(data3);  
}  
  
fetchSequentially();  

此时控制台console的先后顺序是

2.png

发现了另外一个有趣的现象, 我试着调整了一下打印的位置

async function fetchSequentially() {  
const data1 = await fetchData1();  
const data2 = await fetchData2();  
const data3 = await fetchData3(); 

console.log(data1);  
console.log(data2);  
console.log(data3);  
}  

fetchSequentially();  

此时console的顺序变成了

1.png

为什么执行的结果顺序不一致呢? console的位置还能影响到执行顺序? 这里就涉及到JS前端任务执行中任务队列的概念:宏任务、微任务以及主线程。 想要细了解的看这里

在这个示例中,fetchSequentially 函数会依次等待 fetchData1fetchData2 和 fetchData3 完成,并在每个操作完成后打印结果。

并行执行多个异步操作

如果你希望并行执行多个异步操作,可以使用 Promise.all 结合 await

async function fetchInParallel() {  
const [data1, data2, data3] = await Promise.all([  
    fetchData1(),  
    fetchData2(),  
    fetchData3()  
]);  
  
    console.log(data1);  
    console.log(data2);  
    console.log(data3);  
}  
  
   fetchInParallel();  

在这个示例中,fetchInParallel 函数会并行执行 fetchData1fetchData2 和 fetchData3,并在所有操作完成后打印结果。

错误处理

你可以使用 try...catch 块来捕获异步操作中的错误:

async function fetchWithErrorHandling() {  
try {  
  const data1 = await fetchData1();  
  console.log(data1);  
  
  const data2 = await fetchData2();  
  console.log(data2);  
  
  const data3 = await fetchData3();  
  console.log(data3);  
} catch (error) {  
  console.error("An error occurred:", error);  
}  
}  
  
fetchWithErrorHandling();  

在这个示例中,fetchWithErrorHandling 函数会捕获并处理任何一个异步操作中的错误。

结合顺序和并行执行

有时候你可能需要组合顺序和并行执行:

async function fetchCombined() {  
const data1 = await fetchData1();  
console.log(data1);  
  
const [data2, data3] = await Promise.all([fetchData2(), fetchData3()]);  
console.log(data2);  
console.log(data3);  
}  
  
fetchCombined();  

在这个示例中,fetchCombined 函数会首先顺序执行 fetchData1,然后并行执行 fetchData2 和 fetchData3。 此时打印的顺序如下:

image.png

随便记录一下,加深一下记忆