JS循环中正确使用async、await的姿势分享

 更新时间:2021年12月17日 16:28:36   作者:毕了业就退休  
async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案,下面这篇文章主要给大家介绍了关于JS循环中正确使用async、await的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

概览(循环方式 - 常用)

  • for
  • map
  • forEach
  • filter

声明遍历的数组和异步方法

声明一个数组:⬇️

const skills = ['js', 'vue', 'node', 'react']

再声明一个promise的异步代码: ⬇️

function getSkillPromise (value) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(value)
    }, 1000)
  })
}

for 循环中使用

由于for循环并非函数,而async、await需要在函数中使用,因此需要在for循环外套一层function

async function test () {
  for (let i = 0; i < skills.length; i++) {
    const skill = skills[i]
    const res = await getSkillPromise(skill)
    console.log(res)
  }
}

test() // 调用

当使用await时,希望JavaScript暂停执行,直到等待 promise 返回处理结果。上述结果意味着for循环中有异步代码,是可以等到for循环中异步代码完全跑完之后再执行for循环后面的代码。

但是他不能处理回调的循环,如forEach、map、filter等,下面具体分析。

map 中使用

在map中使用await, map 的返回值始是promise数组,这是因为异步函数总是返回promise。

async function test () {
  console.log('start')
  const res = skills.map(async item => {
    return await getSkillPromise(item)
  })
  console.log(res)
  console.log('end')
}

test()

结果:始终为promise数组

start
[
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> }
]
end

若果你想要等到promise的返回结果,可以使用promise.all()处理一下

async function test () {
  console.log('start')
  const res = skills.map(async item => {
    return await getSkillPromise(item)
  })
  const resPromise = await Promise.all(res)
  console.log(resPromise)
  console.log('end')
}

test()

// 结果
start
[ 'js', 'vue', 'node', 'react' ]
end

forEach 中使用

先上代码和结果

async function test () {
  console.log('start')
  skills.forEach(async item => {
    const res = await getSkillPromise(item)
    console.log(res)
  })
  console.log('end')
}

test()

预期结果

'Start'

'js'

'vue'

'node'

'react'

'End'

实际结果 在forEach循环等待异步结果返回之前就执行了console.log('end')

'Start'

'End'

'js'

'vue'

'node'

'react'

JavaScript 中的 forEach不支持 promise 感知,也支持 async 和await,所以不能在 forEach 使用 await 。

filter 中使用

使用filter过滤item为vue或者react的选项

正常使用 filter:

async function test () {
  console.log('start')
  const res = skills.filter(item => {
    return ['vue', 'react'].includes(item)
  })
  console.log(res)
  console.log('end')
}

test() // 调用

// 结果
start
[ 'vue', 'react' ]
end

使用 await后:

async function test () {
  console.log('start')
  const res = skills.filter(async item => {
    const skill = await getSkillPromise(item)
    return ['vue', 'react'].includes(item)
  })
  console.log(res)
  console.log('end')
}

test()

预期结果:

start

[ 'vue', 'react' ]

end

实际结果:

[ 'js', 'vue', 'node', 'react' ]

end

结论:因为异步函数getSkillPromise返回结果返回的promise总是真的,所以所有选项都通过了过滤

附使用小结

  1. 如果你想连续执行await调用,请使用for循环(或任何没有回调的循环)。
  2. 永远不要和forEach一起使用await,而是使用for循环(或任何没有回调的循环)。
  3. 不要在 filter 和 reduce 中使用 await,如果需要,先用 map 进一步骤处理,然后在使用 filter 和 reduce 进行处理。

结语:由于工作中遇到了超大表单抽离组件,异步校验是遇到了此问题,后来经过查阅资料总结出来的结果

总结

到此这篇关于JS循环中正确使用async、await的文章就介绍到这了,更多相关JS循环中使用async、await内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS正则表达式验证数字代码

    JS正则表达式验证数字代码

    本篇文章主要是对JS正则表达式验证数字的代码进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-01-01
  • layer 刷新某个页面的实现方法

    layer 刷新某个页面的实现方法

    今天小编就为大家分享一篇layer 刷新某个页面的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • ajaxControlToolkit AutoCompleteExtender的用法

    ajaxControlToolkit AutoCompleteExtender的用法

    昨天在搜索中使用了这个控件,不过不知道为什么在IE中反应比较慢
    2008-10-10
  • JS实现读取xml内容并输出到div中的方法示例

    JS实现读取xml内容并输出到div中的方法示例

    这篇文章主要介绍了JS实现读取xml内容并输出到div中的方法,涉及javascript针对xml格式数据的读取、遍历、输出等相关操作技巧,需要的朋友可以参考下
    2018-04-04
  • JS实现li标签的删除

    JS实现li标签的删除

    这篇文章主要为大家详细介绍了JS实现li标签的删除,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • 理解javascript定时器中的单线程

    理解javascript定时器中的单线程

    这篇文章主要帮助大家理解javascript定时器中的单线程,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • JavaScript实现计算多维嵌套数组深度

    JavaScript实现计算多维嵌套数组深度

    在前端开发中,经常会遇到需要处理多维嵌套的数据结构,并需要计算出它们的深度,本文就来讲讲如何使用JavaScript实现计算多维嵌套数组深度吧
    2023-06-06
  • 解读Bootstrap v4 sass设计

    解读Bootstrap v4 sass设计

    这篇文章主要介绍了Bootstrap v4 sass设计的相关资料,需要的朋友可以参考下
    2016-05-05
  • 从零搭一个自用的前端脚手架的方法步骤

    从零搭一个自用的前端脚手架的方法步骤

    这篇文章主要介绍了从零搭一个自用的前端脚手架的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • TypeScript高级用法的知识点汇总

    TypeScript高级用法的知识点汇总

    这篇文章主要给大家介绍了关于TypeScript高级用法的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用TypeScript具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-12-12

最新评论