相关文章推荐
性感的鸵鸟  ·  干货分享 | ...·  1 年前    · 

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) // [2,8,18,32]
复制代码

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)
  } // 控制台会输出 name 和 age
复制代码

关于异步函数

和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)
  } // 会输出1
没有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()) 复制代码
  • 中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)
  •