前言:

javascript语言的执行环境是"单线程"。也就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,在执行后面一个任务

这种模式虽然实现起来比较简单,执行环境相对单纯,但是只要一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往是因为莫一段javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法运行。

为了解决这个问题Javascript语言将任务的执行模式分成两种:同步和异步。我们在这里主要来说说 异步编程

一、回调函数

这是异步编程最基本的方法

假如有两个函数f1和f2,后者等待前者的执行结果。如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数。

function f1(callback) {setTimeout(function () {callback();},1000);
}
f1()f2;

采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序的运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行。

回调函数:优点是简单、容易理解和部署。

缺点是不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),流程会很混乱,而且每个任务只能指定一个回调函数。

二、事件监听

采用事件驱动模式。任务的执行不取决于代码的顺序,而取决与某个事件的发生。

以f1和f2为例。先为f1绑定事件

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

f1.trigger(‘done’)表示,执行完成之后,立即触发done事件,从而开始执行f2.

事件监听:优点是可以绑定多个事件,每个事件可以指定多个回调函数,而且可以“去耦合”(Decoupling),有利于实现模块化。

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

三、发布/订阅

发布/订阅模式,又称观察者模式

我们假定,存在一个“信号中心”,某个任务执行完成,就向信号中心“发布”(publish)一个信号,其他任务可以向信号中心“订阅”(subcribe)这个信号,从而知道什么时候自己可以开始执行。

 //f2向信号中心Jquery订阅done信号jQuery.subscribe("done", f2);function f1(){setTimeout(function () {// f1的任务代码//发布done信号jQuery.publish("done");}, 1000);}//f2执行完成后,取消订阅jQuery.unsubscribe("done", f2);

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

四、Promises对象

Promises对象是CommonJs工作提出的一种规范,目的是为了异步编程提供统一接口

他的思想是每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数,比如f1的回调函数f2,可以写成:

 f1().then(f2);function f1(){//deferred对象就是jQuery的回调函数解决方案。var dfd = $.Deferred();setTimeout(function () {// f1的任务代码//将dtd对象的执行状态从"未完成"改为"已完成",从而触发done()方法dfd.resolve();}, 500);//返回promise对象 // deferred.promise()方法。它的作用是,在原来的deferred对象上返回另一个deferred对象,//后者只开放与改变执行状态无关的方法(比如done()方法和fail()方法),//屏蔽与改变执行状态有关的方法(比如resolve()方法和reject()方法),//从而使得执行状态不能被改变。return dfd.promise;}f1().then(f2).then(f3); //指定多个回调函数f1().then(f2).fail(f3); //指定发生错误时的回调函数

Promises对象这种方法优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

五、生成器函数 Generator/yield

Generator函数是 ES6 提供的一种异步编程解决方案。

yield表达式可以暂停函数执行,next方法用于恢复函数执行,这使得Generator函数非常适合将异步任务同步化。
yield表达式本身没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。
每个yield返回的是{value:yield返回的值,done:true/false(执行状态)}

 function *generatorDemo() {yield 'hello';yield 1 + 2;return 'ok';}var demo = generatorDemo()demo.next()  // { value: 'hello', done: false } demo.next()  // { value: 3, done: false } demo.next()  // { value: 'ok', done: ture } demo.next()  // { value: undefined, done: ture }

Generator并不是为异步而设计出来的,它还有其他功能(对象迭代、控制输出、部署Interator接口…)

六、async/await 函数的实现

async是“异步”的意思,而 await 是等待的意思。所以应该很好理解 async 用于申明一个 异步的function (实际上是asnyc function 对象)

await 用于等待一个异步任务执行完成的结果,并且await只等出现在 async 函数中

一个函数如果加上 asnyc,那么该函数就会返回一个 Promise

async function async1() {return "1"
}
console.log(async1()) // -> Promise {<resolved>: "1"}

async函数返回的是一个 Promise 对象,可以使用 then 方法添加回调函数,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
1.await命令后面返回的是 Promise 对象,运行结果可能是rejected,所以最好把await命令放在try…catch代码块中。

 async function test(){let newTime= await new Promise((resolve,reject)=>{//这里等待异步返回结果,再继续向下执行let time = 3000;     setTimeout(()=>{resolve(time);},time)})console.log(newTime+'毫秒后执行');let content = 'test';console.log(content);      //3s后,先输出  “3000毫秒后执行”,再输出 "test"}test()

总结:

简简单单的六种方法:

js 异步编程的进化史:callback -> promise  -> generator -> asnyc + await

JS 异步编程方法:6种方案相关推荐

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

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

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

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

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

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

  4. js异步编程的三种模式

    写在前面 javascript语言的执行环境是"单线程"(single thread),就是指一次只能完成一件任务.如果有多个任务,就必须排队,等前面一个任务完成,再执行后面一个任 ...

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

    js解决异步编程有6种方案: 1.1 回调函数 异步编程的最基本方法,把任务的第二段单独写在一个函数里面,等到重新执行这个任务的时候,就直接调用这个函数. 优点:简单.容易理解和实现. 缺点:多次调用 ...

  6. JS 异步编程六种方案

    前言 我们知道Javascript语言的执行环境是"单线程".也就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务. 这种模式虽然实现起来 ...

  7. js 异步执行_JS Asynchronous — JS 异步编程极简史

    Asynchronous JS 异步编程极简史,这个故事网上已经很多人有了自己的讲述. Event Loop 解释了 Node.js 为何以及如何实现单线程服务模型和 Event Loop.对于 JS ...

  8. 【学习笔记】Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程、手写 Promise(二、JavaScript 异步编程)

    [学习笔记]Part1·JavaScript·深度剖析-函数式编程与 JS 异步编程.手写 Promise(课前准备) [学习笔记]Part1·JavaScript·深度剖析-函数式编程与 JS 异步 ...

  9. promise 浏览器实现的源码_【大前端01-01】函数式编程与JS异步编程、手写Promise...

    [简答题]一.谈谈你是如何理解JS异步编程的,EventLoop.消息队列都是做什么的,什么是宏任务.什么是微任务? 如何理解JS异步编程 众所周知JavaScript语言执行环境是"单线程 ...

最新文章

  1. 迁移学习与跨域推荐,以及解决跨域推荐的方法
  2. Cacti如何实现电话告警
  3. 0215互联网新闻 | TikTok在美月度用户数量过去三个月内增加3000万;5G智能手机测试机首批正式交付...
  4. Bob‘s Problem
  5. Android init.rc 服务启动不成功
  6. EverWeb for Mac(网页设计软件)
  7. echarts绘制地图
  8. 设想一种防U盘病毒的方法,不知道是否管用
  9. Ajax和Json使用入门
  10. 强烈推荐!程序员必备的15 款工具(含阿里内部工具)
  11. 他把我撞了,却骂我diao丝
  12. implicitly has an ‘any‘ type...以及suppressImplicitAnyIndexErrors版本错误TypeScript 5.5问题
  13. 北京大学软件与微电子学院学习经验文章集78篇和1个专题
  14. 阿里的天蝎计划-迟到了N多年的 SI
  15. 聚苯乙烯负载酸性离子液体(P[Vim-PS][HSO4])|活性炭(AC)负载酸性离子液体[Hmim-BS][HSO4]齐岳
  16. 电商生鲜网站开发(二)——后台开发:用户模块
  17. 电信重组又起,对移动软件供应商与SP的影响有哪些!思考:如何从3G网络中找寻我们程序员的价值..
  18. 【安全知识分享】新员工公司级安全生产教育培训(附下载)
  19. Thread类源码解读1--如何创建和启动线程
  20. 金山Office飓风版如今到哪里去了?

热门文章

  1. QLExpress支持的操作符
  2. Unity关于Oculus Quest2 入门开发:(五)基于XR Interaction Toolkit0.10.0开发交互功能之UI篇
  3. pythonpip安装在哪_pippython库安装在哪里了
  4. 玩转 Excel 数据导入
  5. 网络安全篇 ACS 5.6的安装激活-08
  6. Python 自动化-pywinauto库print_control_identifiers()方法打印内容显示不全解决办法,cmd展示更多内容设置方法
  7. 1-FreeRTOS入门指南
  8. 信息化网络工程标书与标书的写作
  9. iOS开发中如何添加应用自己的字体
  10. Linux系统中rides安装