1、回调函数(callback)

      setTimeout(() => {        // callback 函数体      })复制代码

缺点:回调地狱,不能用try catch捕获错误,不能return

回调地狱的根本问题在于:

  • 缺乏顺序性:回调地狱导致的调试困难,和大脑的思维方式不符
  • 嵌套函数存在耦合性,一旦有所改动,就会牵一发而动全身,即(控制反转)
  • 嵌套函数过多的话,很难处理错误
ajax('XXX1', () => {// callback 函数体ajax('XXX2', () => {// callback 函数体ajax('XXX3', () => {// callback 函数体})})
})复制代码

优点:解决了同步的问题(只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行)

2、Promise

Promise就是为了就觉callback的问题而产生的。

Promise实现了链式调用,也就是说每次then后返回的都是一个全新Promise,如果我们在then中return,return的结果会被Promise.resolve()包装

优点:解决了回调地狱的问题

ajax('XXX1').then(res => {// 操作逻辑return ajax('XXX2')}).then(res => {// 操作逻辑return ajax('XXX3')}).then(res => {// 操作逻辑})复制代码

缺点:无法取消Promise,错误需要通过回调函数来捕获

3、Generator

特点:可以控制函数的执行,可以配合co函数库使用

function *fetch() {yield ajax('XXX1', () => {})yield ajax('XXX2', () => {})yield ajax('XXX3', () => {})
}
let it = fetch()
let result1 = it.next()
let result2 = it.next()
let result3 = it.next()复制代码

4、Async/await

async、await是异步的终极解决方案

优点是:代码清晰,不用像Promise写一大堆then链,处理了回调地狱的问题

缺点:await将异步代码改造成同步代码,如果多个异步操作没有依赖性而使用await会导致性能上的降低。

async function test() {// 以下代码没有依赖性的话,完全可以使用 Promise.all 的方式// 如果有依赖性的话,其实就是解决回调地狱的例子了await fetch('XXX1')await fetch('XXX2')await fetch('XXX3')
}复制代码

下面来看一个使用await的例子:

let a = 0
let b = async () => {a = a + await 10console.log('2', a) // -> '2' 10
}
b()
a++
console.log('1', a) // -> '1' 1复制代码

对于以上代码你可能会有疑惑,让我来解释下原因

  • 首先函数b先执行,在执行到await 10之前变量 a 还是0,因为 await 内部实现了generator,generator 会保留堆栈中东西,所以这时候 a = 0 被保存了下来
  • 因为await 是异步操作,后来的表达式不返回 Promise 的话,就会包装成 Promise.resolve(返回值),然后会去执行函数外的同步代码
  • 同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来适用,这时候 a = 0 + 10

上述解释中提到了await 内部实现了 generator ,其实 await 就是 generator 加上 Promise 的语法糖,且内部实现了自动执行generator。详情可参考然阮一峰的ES6 es6.ruanyifeng.com/#docs/array

转载于:https://juejin.im/post/5d40efc96fb9a06ae94d0dc5

记录:JS异步解决方案的发展以及优缺点相关推荐

  1. 【面试题】聊聊 js 异步解决方案

    大厂面试题分享 面试题库 前端面试题库 (面试必备)   推荐:★★★★★ 地址:前端面试题库 前言 继续聊聊 js 的异步解决方案有哪些,以及各个方案的优缺点是什么...... 回调函数(callb ...

  2. js异步解决方案 --- 回调函数 vs promise vs generater/yield vs async/await

    javascript -- 深度解析异步解决方案 高级语言层出不穷, 然而唯 js 鹤立鸡群, 这要说道js的设计理念, js天生为异步而生, 正如布道者朴灵在 node深入浅出--(有兴趣的可以读一 ...

  3. JS 异步编程都有哪些方案?

    什么是同步? 所谓的同步就是在执行某段代码时,在该代码没有得到返回结果之前,其他代码暂时是无法执行的,但是一旦执行完成拿到返回值之后,就可以执行其他代码了.换句话说,在此段代码执行完未返回结果之前,会 ...

  4. JS 异步编程都有哪些方案

    JS 异步编程都有哪些方案   先一起来回想一下,我们在日常开发中都用过哪些 JS异步编程的方式?总结起来无外乎有这几种:回调函数.事件监听.Promise.Generator.async/await ...

  5. 切面是异步还是同步操作‘_细说JS异步发展历程

    知其然知其所以然,首先了解三个概念: 1.什么是同步? 所谓同步,就是在发出一个"调用"时,在没有得到结果之前,该"调用"就不返回.但是一旦调用返回,就得到返回 ...

  6. js async await 终极异步解决方案

    js async await 终极异步解决方案 参考文章: (1)js async await 终极异步解决方案 (2)https://www.cnblogs.com/CandyManPing/p/9 ...

  7. JS 异步发展流程(回调函数=Async/await)

    异步编程的语法目标,就是怎样让它更像同步编程 什么是异步? 异步任务指的是,不进入主线程.而进入"任务队列"(task queue)的任务,只有"任务队列"通知 ...

  8. JS 异步编程的 5 种解决方案

    我们知道 JS 语言的执行环境是"单线程",所谓"单线程",就是指一次只能完成一件任务,这种模式的好处是实现起来比较简单,执行环境相对单纯:坏处是只要有一个任务 ...

  9. js异步编程解决方案

    这里所说的异步解决方案,主要针对了多个异步操作,并且异步操作之间相互依赖,这里总结一下解决方案. 1.回调函数 这是最古老的方法,尽管能解决异步相互依赖的情况,但是当异步操作过多,多层嵌套的回调函数会 ...

最新文章

  1. Ubuntu16.04安装视觉SLAM环境(OpenCV)
  2. C++泛型编程:template模板
  3. bzoj3545 Peaks
  4. oracle查看表和索引碎片,Oracle 表空间索引存储与碎片检查
  5. 创建squashfs.img文件挂载失败
  6. 原来流行也可以变成怀旧!
  7. Spring Cloud和Dubbo
  8. mysql 拷贝安装_Mysql的安装和主从复制
  9. Java BigInteger类| toByteArray()方法与示例
  10. 面试官:缓存一致性问题怎么解决?
  11. 小强的HTML5移动开发之路(50)——jquerymobile页面初始化过程
  12. 程序在发布前就应该发现的一些错误
  13. 北航操作系统课程-20200409课堂小测-进程同步
  14. bzoj4565 [Haoi2016]字符合并 (区间DP + 状压DP)
  15. 深恶痛绝……残忍虐杀何时终止?
  16. 《基因 7》(GENE VII)问题汇编
  17. 博易终于发布新版本了
  18. this is related to npm not being able to find a file
  19. wagon-maven-plugin插件实现自动化构建部署到服务器
  20. 机器人路径规划_人工势场法

热门文章

  1. JavaScript写贪吃蛇游戏,代码思路都有,想学的自己看
  2. Exception.InnerException 属性的使用
  3. 诺基亚对塞班的支持将持续到2016年
  4. 电脑 你离我有多远!
  5. Windows 7里的计算器,中文版,给Vista和2008用吧
  6. udf、utaf、udtf进出数量规律
  7. ubuntu19.10 安装搜狗输入法
  8. redis的各种数据集的列举功能
  9. 在Ubuntu Linux 16.04下(64位)打开.ipynb文件
  10. 【机器学习】数据挖掘算法——关联规则(一),相关概念,评价指标