forEach是并行的对每个元素执行函数。所以await不会阻碍循环和代码的执行
const arr = [1, 2, 3]
async function wait (time) {
const now = Date.now()
return new Promise((res, rej) => {
setTimeout(() => {
console.log('我是异步执行的函数')
res()
}, time)
arr.forEach(async (item) => {
await wait(1000)
console.log(item)
return item * 2
console.log(arr)
复制代码
打印结果为:
原因:forEach中的异步函数不生效,所以会直接执行
console.log(arr)
,大约1秒后会执行完异步函数,然后执行对应的console.log(item).这里的执行顺序和浏览器的event loop机制相关。
如果想要确保异步代码执行完成后再继续执行,可以使用Promise.all。上面的代码可以改写成:
const arr = [1, 2, 3]
async function wait (time) {
const now = Date.now()
return new Promise((res, rej) => {
setTimeout(() => {
console.log('我是异步执行的函数')
res()
}, time)
let asyncFuncs = []
arr.forEach(async (item) => {
asyncFuncs.push(wait(1000))
console.log(item)
return item * 2
Promise.all(asyncFuncs).then(() => {
console.log(arr)
forEach循环里不能有break或continue, 会产生报错
callback可以使用return但return的结果没有作用,只是提前结束函数运行,也就是calback总是返回undefined
forEach返回值undefined
Array.prototype.map
map方法和forEach相似,但map方法会创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
参数:和forEach相同
异步函数执行上map和forEach相同,await不生效
循环里不能有break或continue, 会产生报错
callback的return 返回新的数组元素,不使用return时等价于返回undefined
const array = [1, 4, 9, 16]
const map = array.map(x => x * 2)
console.log(map)
复制代码
for
使用:for(let i = 0; i < 10; i += 1){}
。
关于异步函数
await在for循环中是生效的,即,循环会一个完成后继续执行下一个。
关于break和continue
for循环中可以使用break continue。break会结束循环,继续执行代码。continue是结束本次循环。
for循环中没有return。如果使用会产生报错Uncaught SyntaxError: Illegal return statement
for...of
for...of语句在可迭代对象上创建一个迭代循环,执行语句。可迭代对象是指对象具有Iterator接口。也就是如果一个变量具有Iterator接口,就可以用for..in方法去循环遍历。Array和Map都是可迭代对象,但对象上是没有iterator接口的。如果想在对象上使用iterator方法,可以在对象的Symbol.iterator上写个Iterator函数。例如:
const person = {
name: 'Amy',
age: 18,
[Symbol.iterator] () {
return Object.keys(this)[Symbol.iterator]()
for (let item of person) {
console.log(item)
}
复制代码
关于异步函数
和for循环一样,会等待await执行完后继续执行。例如:
async function wait (time) {
const now = Date.now()
return new Promise((res, rej) => {
setTimeout(() => {
console.log('我是异步执行的函数')
res()
}, time)
const arr = [1, 2, 3]
async function test () {
for (let i of arr) {
console.log(i)
await wait(1000)
test()
复制代码
执行结果:
关于continue和break
和for循环相同, break跳出循环;continue跳出本次循环继续执行
const arr = [1, 2, 3]
for (let i of arr) {
if (i === 2) {break}
console.log(i)
}
没有return 会报错
for...in
和 for 循环及for..of一样依次执行代码。
break和continue
会忽略break和continue
for...in中也没有return
forEach和map,await不生效;使用break或continue会报错
for循环、for...in,for...of,支持await,for和for...of中可以使用break和continue;for...in会忽略continue和break
开发过程中,根据使用场景,有些可以并行执行,有些情况需要依次执行一组异步函数。可以封装一个方法来执行。
* 并行执行一组方法
* @params {Array<Object>} funcArr 一组待执行的函数{func: asyncFunc, params: funcParams}
* @returns {Array<Promise>} 函数执行结果(按数组顺序返回)
* @example
* excuteInParallel([{func: asynFuc1, params: 2},{func: asynFuc2, params: {param: 1}}}])
let ret = []
async function excuteInParallel (funcArr = []) {
const result = funcArr.map((item) => {
if (item.params) {
return item.func(item.params)
return item.func()
return Promise.all(result)
* 串行执行一组异步方法
* @params {Array<Object>} funcArr 一组待执行的函数{func: asyncFunc, params: funcParams}
* @returns {Array<Promise>} 函数执行结果(按数组顺序返回)
* @example
* excuteInParallel([{func: asynFuc1, params: 2},{func: asynFuc2, params: {param: 1}}}])
async function excuteInSeries (funcArr = []) {
const result = []
for (const item of funcArr) {
if (item.params) {
result.push(await item.func(item.params))
} else {
result.push(await item.func())
复制代码