每天3分钟,重学ES6-ES12(十五)异步代码处理方案

简介: 每天3分钟,重学ES6-ES12(十五)异步代码处理方案

19c2e7a9bfbb7f5e8c7d744db995e29.png

每天3分钟,重学ES6-ES12文章汇总

前言

今天开始和大家一起系统的学习ES6+,每天3分钟,用一把斗地主的时间,重学ES6+,前面我们介绍了promise,生成器和迭代器,async await,现在我们总结一下针对异步代码处理方案

业务场景

请求一个接口,拿到返回值,对返回值进行处理,当作第二个接口的请求参数,拿到返回值处理,当作第三个接口的请求参数。最终数据需要调用依次调用3个接口才能拿到。

  • 1> url: why -> res: why
  • 2> url: res + "aaa" -> res: whyaaa
  • 3> url: res + "bbb" => res: whyaaabbb
function requestData(url) {
  // 异步请求的代码会被放入到executor中
  return new Promise((resolve, reject) => {
    // 模拟网络请求
    setTimeout(() => {
      // 拿到请求的结果
      resolve(url)
    }, 2000);
  })
}

方案一 回调函数

优点:便于理解 缺点:回调地狱,不能捕获错误

ajax('url', () => {
    // callback 函数体
    ajax('url', () => {
        // callback 函数体
        ajax('url', () => {
            // callback 函数体
        })
    })
})


方案二 事件监听

f1.on('done', f2); 
function f1(){     
     setTimeout(function () {       
     // f1的任务代码      
     f1.trigger('done');     
     }, 1000);   
}

优点:容易理解,可以绑定多个事件,每个事件可以指定多个回调函数;

缺点:整个流程都要变成事件驱动型,运行流程会变得不清晰。

方案三 发布订阅模式

jQuery.subscribe("done", f2);
function f1(){
    setTimeout(function () {
      // f1的任务代码
      jQuery.publish("done");
    }, 1000);
}
jQuery.unsubscribe("done", f2);

与"事件监听"类似,但是明显优于后者。因为我们可以通过查看"消息中心",了解存在多少信号、每个信号有多少订阅者,从而监控程序的运行。

方案四 Promise中then的返回值来解决回调问题

requestData("why").then(res => {
   return requestData(res + "aaa")
}).then(res => {
   return requestData(res + "bbb")
}).then(res => {
   console.log(res)
})

优点:解决了层层回调问题,相对直观 缺点:无法精确捕获到哪个promise错误,链式调用依然不如同步函数代码直观

方案五 Promise + generator实现

function* getData() {
  const res1 = yield requestData("why")
  const res2 = yield requestData(res1 + "aaa")
  const res3 = yield requestData(res2 + "bbb")
  const res4 = yield requestData(res3 + "ccc")
  console.log(res4)
}
// 1> 手动执行生成器函数
const generator = getData()
generator.next().value.then(res => {
  generator.next(res).value.then(res => {
    generator.next(res).value.then(res => {
      generator.next(res)
    })
  })
})
// 2> 自己封装了一个自动执行的函数
function execGenerator(genFn) {
  const generator = genFn()
  function exec(res) {
    const result = generator.next(res)
    if (result.done) {
       return result.value
    }
    result.value.then(res => {
       exec(res)
    })
   }
   exec()
execGenerator(getData)

优点:代码直观,* yield 可以重新组织代码,同步的方式执行异步代码

缺点:无法执行并发请求,只能调用next()一步一步请求,* yield 对开发者不太友好,难以理解

方案六 async/await

async function getData() {
  const res1 = await requestData("why")
  const res2 = await requestData(res1 + "aaa")
  const res3 = await requestData(res2 + "bbb")
  const res4 = await requestData(res3 + "ccc")
  console.log(res4)
}
getData()

async 是generator的语法糖 内置执行器,无需手动执行next()方法

*/yield  => async/await

优点:在generator 的基础上更加语义化,使用简单,无需执行next 方法 缺点:无法执行并发请求,必须有try catch才能捕获到异常

业务使用

Promise + async/await

async/await是基于generator的语法糖,返回的也是一个promise,所以返回值可以调用promise的方法。 当处理并发一般Promise.all + async/awit 结合使用

async function getData(){
    await Promise.all([requestData(a),requestData(b)])
}

总结

async await意义在于‘期望异步代码和同步代码可以流畅混淆而不至于被 then 分割’。同步代码不多的情况,async await和promise的使用可以取决于个人喜好。

async/await设计初衷并不是为了取代Promise,而是为了让使用Promise更加方便。

JS异步的发展历程是callback->promise/generator->async/await

这三种历程我认为并没有 相互优越的区别,而是有使用场景的区别

注册事件必须是用回调,async await 可以梳理平常的业务代码 更容易理解拆分业务 ,而generator 适用于需要暂停的业务逻辑,promise 适用于 构建通用异步函数



相关文章
|
存储 Java 程序员
100道最新Java面试题,常见面试题及答案汇总(上)
100道最新Java面试题,常见面试题及答案汇总
372 0
|
12月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习中的卷积神经网络(CNN)及其应用
【9月更文挑战第24天】本文将深入探讨深度学习中的一种重要模型——卷积神经网络(CNN)。我们将通过简单的代码示例,了解CNN的工作原理和应用场景。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息。
295 1
|
8月前
|
弹性计算 运维 监控
自动化AutoTalk第十一期-应知必会的自动化工具之阿里云配额中心
本次分享主题为“应知必会的自动化工具之阿里云配额中心”,课程围绕三个方面展开:1) 认识配额及其作用;2) 配额管理的意义与方法;3) 阿里云配额中心的功能和使用场景。通过学习,了解如何有效管理和监控配额,避免资源限制影响业务,并实现自动化集成,提升运维效率。
163 10
|
机器学习/深度学习 人工智能 自然语言处理
智能笔下的学术:AI在学术写作中的革新应用
【7月更文第31天】随着人工智能技术的发展,AI工具已经成为学术界不可或缺的一部分。它们不仅能够帮助研究人员提高工作效率,还能提升论文的质量。本文将介绍一些流行的AI学术写作工具,并探讨它们如何重塑学术研究的过程。
1347 0
|
前端开发 Python
60行Python代码开发在线markdown编辑器
60行Python代码开发在线markdown编辑器
199 2
|
域名解析 网络协议
Namesilo域名解析
简单的3步,就可以让你快速完成Namesilo域名解析设置,修改DNS解析记录。首先你需要登录Namesilo官网,点击My Account进入账户主页,然后点击Domain Manager打开Namesilo域名管理控制台。找到你想要解析的域名,在其右侧点击蓝色小球图标进入域名修改界面,添加和删除你的域名解析记录。
1993 0
Namesilo域名解析
|
机器学习/深度学习 并行计算 算法
掌握XGBoost:GPU 加速与性能优化
掌握XGBoost:GPU 加速与性能优化
2058 0
|
消息中间件 Kafka 开发工具
使用C语言操作kafka ---- librdkafka
使用C语言操作kafka ---- librdkafka
322 1
|
Linux 数据库
Linux 常用基础命令(2024年最新篇)新手小白必看 初识Linux
Linux 常用基础命令(2024年最新篇)新手小白必看 初识Linux
116 1
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的大学生就业信息管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的大学生就业信息管理系统附带文章和源代码部署视频讲解等
103 0