【收藏】五种在循环中使用 async/await 的方法

简介: 本篇总结了 5 种在循环中使用 async/await 的方法(代码干货都能在浏览器控制台自测):

image.png

我们经常会遇到这样的需求,在循环中使用异步请求,而 ES6 的 async/await 是我们让异步编程更简单的利剑🗡。


本篇总结了 5 种在循环中使用 async/await 的方法(代码干货都能在浏览器控制台自测):

  • 打勾的方法 ✔:表示在循环中每个异步请求是按照次序来执行的,我们简称为 “串行”
  • 打叉的方法 ❌ :表示只借助循环执行所有异步请求,不保证次序,我们简称为 “并行”

按需所取,点赞👍收藏📕

image.png


forEach ❌



首先,想到遍历,我们常用 forEach,用 forEach 可以吗?来试试~

首先要明确的是,本质上 forEach 就是一个 for 循环的包装。


Array.prototype.forEach = function (callback) {
  for (let index = 0; index < this.length; index++) {
    callback(this[index], index, this)
  }
}


在回调函数内部调用 await 需要这个回调函数本身也是 async 函数,所以在【循环+ async/await】中的代码应这样写:


async function someFunction(items) {
  items.forEach( async(i) => {
     const res = await someAPICall(i);
     console.log('--->', res);
  });
}
function someAPICall(param) {
    return new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve("Resolved" + param)
      },param);
    })
}
someFunction(['3000','8000','1000','4000']);


在控制台执行,如图:


image.png


我们可以看到 forEach 并没有串行输出结果。forEach 只是把所有请求执行了,谓之并行


for...of... ✔



事实上 for...of 却符合我们串行的要求。

思路如下:


async function printFiles () {
  let fileNames = ['picard', 'kirk', 'geordy', 'ryker', 'worf'];
  for (const file of fileNames) {
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  }
}


针对本文例,代码如下:

async function someFunction(items) {
 for (const i of items){
     const res= await someAPICall(i)
     console.log('--->', res);
 }
}
function someAPICall(param) {
    return new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve("Resolved" + param)
      },param);
    })
}
someFunction(['3000','8000','1000','4000']);


控制台执行如下图:

image.png


reduce ✔



有了解过【循环】+【异步】的童鞋肯定知道 reduce。它可以称得上是精华所在!


代码如下:


function testPromise(time) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`Processing ${time}`);
      resolve(time);
    }, time);
  });
}
let result = [3000,2000,1000, 4000].reduce( (accumulatorPromise, nextID) => {
  return accumulatorPromise.then(() => {
    return testPromise(nextID);
  });
}, Promise.resolve());
result.then(e => {
  console.log("All Promises Resolved !!✨")
});


我们可以使用 reduce 函数来遍历数组并按顺序 resolve promise。

很清晰!自行控制台体验。


generator ✔



其实用 async generator 也是可以的。

async function* readFiles(files) {
  for(const file of files) {
    yield await readFile(file);
  }
};


针对本文例,代码如下:


async function* generateSequence(items) {
  for (const i of items) {
    await new Promise(resolve => setTimeout(resolve, i));
    yield i;
  }
}
(async () => {
  let generator = generateSequence(['3000','8000','1000','4000']);
  for await (let value of generator) {
    console.log(value);
  }
})();


自行控制台体验。


Promise.all ❌



如果你不用考虑异步请求的执行顺序,你可以选择 Promise.all(),即 Promise.all() 可以达到 并行 的目的。它也能保证你的请求都被执行过。

async function printFiles () {
  let fileNames = ['picard', 'kirk', 'geordy', 'ryker', 'worf'];
  await Promise.all(fileNames.map(async (file) => {
    const contents = await fs.readFile(file, 'utf8');
    console.log(contents);
  }));
}


针对本文例,代码如下:


async function promiseAll(arr) {
  await Promise.all(arr.map(async (i) => {
    await sleep(i)
    console.log('--->', i);
  }))
}
function sleep(i) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, i)
  })
}
promiseAll(['3000','8000','1000','4000'])


自行控制台体验。

好啦~


本次总结就到这!主要是代码部分,自己敲一敲,或者跑一跑、改一改,感受感受异同。


正所谓“代码用时方恨少呀“!😄按需所取,点赞👍收藏📕。

关注我的公众号【掘金安东尼】,持续输出中......


相关文章
|
8月前
|
前端开发
Await和Async是什么?跟Promise有什么区别 使用它有什么好处
Await和Async是什么?跟Promise有什么区别 使用它有什么好处
|
8月前
|
前端开发 JavaScript
【面试题】async/await、promise和setTimeout的执行顺序
【面试题】async/await、promise和setTimeout的执行顺序
105 0
|
2月前
|
前端开发 JavaScript
async/await和Promise在性能上有什么区别?
性能优化是一个综合性的工作,除了考虑异步模式的选择外,还需要关注代码的优化、资源的合理利用等方面。
45 4
|
3月前
|
前端开发 JavaScript
setTimeout、Promise、Async/Await 的区别
`setTimeout` 是用于延迟执行函数的简单方法;`Promise` 表示异步操作的最终完成或失败;`Async/Await` 是基于 Promise 的语法糖,使异步代码更易读和维护。三者都用于处理异步操作,但使用场景和语法有所不同。
|
8月前
|
前端开发 JavaScript 开发者
阿珊带你深入理解 async/await 函数
阿珊带你深入理解 async/await 函数
|
5月前
|
C#
C# async await 异步执行方法
C# async await 异步执行方法
62 0
|
5月前
|
前端开发 JavaScript
如何在forEach内使用异步调用 async/await
如何在forEach内使用异步调用 async/await
|
8月前
|
前端开发
Promise和async/await之间有什么区别
Promise与async/await是异步编程的两种模式。Promise使用.then()和.catch()处理回调,语法较复杂,易出现回调地狱;而async/await提供更清晰的顺序代码,使用try/catch进行错误处理,使异步操作更易读、易维护。Promise在控制流和错误堆栈方面较为灵活,但定位错误难,而async/await自动等待、线性控制流,错误堆栈清晰。两者各有优势,选择取决于具体需求和偏好。
|
8月前
|
前端开发
promise和async的区别是什么?
promise和async的区别是什么?
103 1
|
前端开发 JavaScript
从 async 和 await 函数返回值说原理
昨天在文章《JavaScript中的 async 和 await》中简单的介绍了其使用方法。那么 async 和 await 如何工作,如何正确的使用 async 和 await 。
413 0