JS 异步已经告一段落了,这里来一波小总结

1. 回调函数(callback)

setTimeout(() => {
// callback 函数体
}, 1000)

缺点:回调地狱,不能用 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 10
console.log('2', a) // -> '2' 10
}
b()
a++
console.log('1', a) // -> '1' 1

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

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

上述解释中提到了 await 内部实现了 generator,其实 await 就是 generator 加上 Promise的语法糖,且内部实现了自动执行 generator。如果你熟悉 co 的话,其实自己就可以实现这样的语法糖。

js中异步方案比较完整版(callback,promise,generator,async)的更多相关文章

  1. 一个例子读懂 JS 异步编程: Callback / Promise / Generator / Async

    JS异步编程实践理解 回顾JS异步编程方法的发展,主要有以下几种方式: Callback Promise Generator Async 需求 显示购物车商品列表的页面,用户可以勾选想要删除商品(单选 ...

  2. Callback, Promise和Async/Await的对比

    Callback, Promise和Async/Await的对比 Callback Hell getData1(function (data1) { console.log('我得到data1了') ...

  3. Web worker 与JS中异步编程的对比

    0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何 ...

  4. 关于js中异步问题的解决方案

    在js中有一个始终无法绕过的问题,如何优雅地解决异步问题.实际上,js在执行过程中,每遇到一个异步函数,都会将这个异步函数放入一个异步队列中,只有当同步线程执行结束之后,才会开始执行异步队列中的函数, ...

  5. 用JS制作一个信息管理平台完整版

      前  言 JRedu 在之前的文章中,介绍了如何用JS制作一个实用的信息管理平台. 但是那样的平台功能过于简陋了,我们今天来继续完善一下. 首先我们回顾一下之前的内容.   1.JSON的基础知识 ...

  6. 一篇文章彻底搞懂异步,同步,setTimeout,Promise,async

    之前翻看别的大佬的博客看到了关于setTimeout,promise还有async执行顺序的文章.观看了几篇之后还是没有怎么看懂,于是自己开始分析代码,并整理了此文章,我相信通过此文章朋友们能对异步同 ...

  7. js对数组去重的完整版

    数组去重是很常见的一个需求,而各种各样的姿势也很多,常见的如indexOf,或者hash,但是他们还是有缺陷,这里我查了一些资料做补充. 一般方式 //一般方法->使用indexOf Array ...

  8. 基于JS的身份证验证(完整版)

    var Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 ]; // 加权因子 var ValideCode = [ 1, 0 ...

  9. java--css+js做的树形菜单(完整版)

    jsp页面: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8 ...

随机推荐

  1. SCUT - 15 - 为美好的世界献上爆炎 - dfs

    https://scut.online/p/15 样例错了,按题目说的去做就AC了. 反向搜索使得最终比较strncmp的时候复杂度下降了很多(虽然应该可行性剪枝也少了) #include<bi ...

  2. window安装android打包环境

    1.下载jdkhttp://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载:jdk-8u1 ...

  3. redis win系统安装并设置开机自启

    安装包下载网址 :https://github.com/MSOpenTech/redis/releases 找到最新发布的安装包进行下载 下载完后解压到c盘 打开cmd,并进到redis里面 cd C ...

  4. hdu1754(线段树单点替换&区间最值模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754 题意:中文题诶- 思路:线段树单点替换&区间最大值查询模板 代码: #include & ...

  5. 洛谷 P2216 [HAOI2007]理想的正方形

    P2216 [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一 ...

  6. 使用Unity容器实现属性注入

    简介 Unity :是微软用C#实现的轻量级,可扩展的依赖注入容器. 控制反转:(Inversion of Control,缩写为IoC),是用来消减程序之间的耦合问题,把程序中上层对下层依赖,转移到 ...

  7. 关于APICloud使用心得(原创)

    从最开始接触APICloud到现在已经有一段时间了.现在想说说自己对于APICloud开发移动端的想法,既有利又有弊. 以下都是我个人的观点. 先说优点吧: 1.APICloud平台文档.视频较多,很 ...

  8. java之代理 静态代理和动态代理

    一.静态代理     1. 代理有很多种,有虚拟代理,保护代理,智能引用代理,和远程代理; 开发中最常用的是只能引用代理       2. 代理的模式有两种,分别是: 静态代理 代理对象,被代理对象在 ...

  9. HBase中报错 java.lang.NoClassDefFoundError: com/google/protobuf/LiteralByteString

    Protobuf(全称 Protocol Buffers)是 Google 开发的一种数据描述语言,能够将结构化数据序列化,可用于数据存储.通信协议等方面.在 HBase 里面用使用了 Protobu ...

  10. Maven入门 项目的生命周期&pom.xml配置&仓库