我们经常会遇到这样的需求,在循环中使用异步请求,而 ES6 的 async/await 是我们让异步编程更容易的利剑。
本文总结了5种循环使用async/await的方法(代码可在浏览器控制台自测):
首先,想到遍历,我们常用 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']);
在控制台执行,我们可以看到 forEach 并没有串行输出结果。forEach 只是把所有请求执行了,谓之并行。
事实上 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']);
有了解过【循环】+【异步】的童鞋肯定知道 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。
很清晰!自行控制台体验。
其实用 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() 可以达到 并行 的目的。它也能保证你的请求都被执行过。
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'])
自行控制台体验。
本文章来自于公众号「掘金安东尼」
虽然大家知道async/await,但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await
Async实际上是一个封装了自动化执行并返回一个Promise的Generator函数的语法糖。这句话的意思我们可以分为三个部分来解读:首先它有一个自动化执行,Generator函数是依靠不停的调用.net来依次执行的,Async有一个自动化执行的过程
Node.js7.6起, Node.js 搭载了有async函数功能的V8引擎。当Node.js 8于10月31日成为LTS版本后,我们没有理由不使用async函数。接下来,我将简要介绍async函数,以及如何改变我们编写Node.js应用程序的方式。
自2015年11 发布1.7版以来,TypeScript 已支持 async/await 关键字。编译器使用 yield 将异步函数转换为生成器函数。这意味着咱们无法针对 ES3 或 ES5,因为生成器仅在 ES6 中引入的。
async/await 大家肯定都用过,在处理异步操作的时候真的是很方便。那今天主要讲一些在使用 async/await 时容易忽略和犯错的地方。上面的代码中,每一行都会 等待上一行的结果返回后才会执行。
有一个图片列表,我想要在图片onload成功之后获取加载成功的图片列表,图片资源加载为异步,我们使用ES7的async await方式实现,多张图片,是用for循环。
Async 和 Awaiit 是 Promise 的扩展,我们知道 JavaScript 是单线程的,使用 Promise 之后可以使异步操作的书写更简洁,而 Async 使 Promise 像同步操作
最近代码写着写着,我突然意识到一个问题——我们既然已经有了 Promise 和 then,为啥还需要 async 和 await?这不是脱裤子放屁吗?
如果让你手写async函数的实现,你是不是会觉得很复杂?这篇文章带你用20行搞定它的核心。经常有人说async函数是generator函数的语法糖,那么到底是怎么样一个糖呢?让我们来一层层的剥开它的糖衣。
async/await是ES7的写法,可以让非同步call back写法看起来像同步的顺序去执行。以下我们new一个Promise的class并return给一个function
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!