每天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 适用于 构建通用异步函数



相关文章
|
6月前
|
前端开发 JavaScript 网络架构
谈谈你对 ES6 的理解
谈谈你对 ES6 的理解
30 1
|
6月前
|
前端开发
【面试题】如何使用ES6 ... 让代码优雅一点?
【面试题】如何使用ES6 ... 让代码优雅一点?
|
6月前
|
前端开发
【前端学习】—ES6新增的方法有哪些(十五)
【前端学习】—ES6新增的方法有哪些(十五)
|
前端开发 JavaScript Java
【编程指南】ES2016到ES2023新特性解析一网打尽(二)
【编程指南】ES2016到ES2023新特性解析一网打尽(二)
149 0
|
JSON JavaScript 前端开发
【编程指南】ES2016到ES2023新特性解析一网打尽(一)
【编程指南】ES2016到ES2023新特性解析一网打尽(一)
100 0
|
前端开发
前端学习笔记202306学习笔记第四十二天-Es7-ES7新增特性
前端学习笔记202306学习笔记第四十二天-Es7-ES7新增特性
55 0
|
前端开发
前端学习笔记202306学习笔记第四十二天-Es8-ES8和ES9新增特性2
前端学习笔记202306学习笔记第四十二天-Es8-ES8和ES9新增特性2
62 0
|
前端开发
前端学习笔记202306学习笔记第四十二天-Es8-ES8和ES9新增特性1
前端学习笔记202306学习笔记第四十二天-Es8-ES8和ES9新增特性1
58 0
|
JavaScript 前端开发
每天3分钟,重学ES6-ES12(十六)错误异常处理方案
每天3分钟,重学ES6-ES12(十六)错误异常处理方案
111 0
|
前端开发 JavaScript 小程序
每天3分钟,重学ES6-ES12(十七)模块化历史
每天3分钟,重学ES6-ES12(十七)模块化历史
88 0