美文网首页
JavaScript异步编程

JavaScript异步编程

作者: 夏知更 | 来源:发表于2018-08-27 20:49 被阅读11次
前言
  • JS单线程的局限
    由于JS"单线程"的特点,一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务。

    但是,只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

  • 解决办法
    为了解决这个问题,JS添加了异步执行模式。"异步模式"每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

一、事件监听

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

请求1(function(请求结果1).on('done', 请求2(function(请求结果2));

当请求1发生done事件,就执行请求2,改写为:

请求1(function(请求结果1)){
    setTimeout(function () {
      请求1.trigger('done');
    }, 1000);
  }

请求.trigger('done')表示,执行完成后,立即触发done事件,从而开始执行请求。

  • 优点
    这种方法的优点是比较容易理解,可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合",有利于实现模块化。
  • 缺点
    缺点是整个程序都要变成事件驱动型,运行流程会变得很不清晰。
二、回调函数

需要根据前一个网络请求的结果,再去执行下一个网络请求,代码大概如下:

请求1(function(请求结果1){
  setTimeout(function () {
    请求2(function(请求结果2){
                  ...
              })
  }, 1000);
}

这样,就将同步变成了异步操作,请求1不会阻塞程序运行,先执行程序的主要逻辑,将耗时的操作推迟执行。

  • 优点
    回调函数的优点是简单、容易理解和部署。
  • 缺点
    缺点是不利于代码的阅读和维护,各个部分之间高度耦合,流程会很混乱,而且每个任务只能指定一个回调函数。

随着回调函数的增加,很容易陷入回调地狱,为了解决回调地狱的问题,一般采用Promise作为解决方案。

三、发布/订阅

我们可以监听某一事件,当事件发生时,进行相应回调操作;另一方面,当某些操作完成后,通过发布事件触发回调。这样就可以将原本捆绑在一起的代码解耦。

jQuery.subscribe("done", f2);

改写:

 请求1(function(请求结果1){
    setTimeout(function () {
      jQuery.publish("done");
    }, 1000);
  }

jQuery.publish("done")的意思是,请求1执行完成后,向"信号中心"jQuery发布"done"信号,从而引发请求2的执行。此外,请求2完成执行后,也可以取消订阅(unsubscribe)。

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

四、Promise

Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。现已被 ES6 纳入进规范中。
Promise是一个方案,用来解决多层回调嵌套的解决方案。

需要根据前一个网络请求的结果,再去执行下一个网络请求,代码大概如下:

请求1(function(请求结果1){
    请求2(function(请求结果2){
        请求3(function(请求结果3){
            请求4(function(请求结果4){
                请求5(function(请求结果5){
                    请求6(function(请求结果3){
                        ...
                    })
                })
            })
        })
    })
})

回调地狱带来的负面作用有以下几点:
1、代码臃肿;
2、可读性差;
3、耦合度过高,可维护性差;
4、代码复用性差;
5、容易滋生 bug;
6、只能在回调里处理异常;
为了能使用一种更加友好的代码组织方式,解决异步嵌套的问题:

let 请求结果1 = 请求1();
let 请求结果2 = 请求2(请求结果1);
let 请求结果3 = 请求3(请求结果2);
let 请求结果4 = 请求2(请求结果3);
let 请求结果5 = 请求3(请求结果4);
  • 优点
    这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,可以实现很多强大的功能。如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。
  • 缺点
    缺点就是编写和理解,都相对比较难。
扩展(Generator和async / await)
  • Generator
    generator是es6中的一个新的语法。在function关键字后添加*即可将函数变为generator
const gen = function* () {
    yield 1;
    yield 2;
    return 3;
}

let g = gen();
g.next(); // { value: 1, done: false }
g.next(); // { value: 2, done: false }
g.next(); // { value: 3, done: true }
g.next(); // { value: undefined, done: true }

  • async/await
    es7中的async/await
    在async函数中可以使用await语句,await后一般是一个Promise对象。
async function foo () {
    console.log('开始');
    let res = await post(data);
    console.log(`post已完成,结果为:${res}`);
};

相关文章

  • JavaScript异步编程好文摘要

    JavaScript之异步编程简述JavaScript异步编程

  • part1整理

    函数式编程:JavaScript函数式编程指南 异步编程:异步编程 Promise源码 JavaScript基础知...

  • 一篇看完JS异步编程的进阶史

    一、Javascript实现异步编程的过程以及原理 1、为什么要用Javascript异步编程 众所周知,Java...

  • ES6 之 Promise

    Promise是JavaScript异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步...

  • JavaScript(ES6) - Async

    异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...

  • 异步编程控制方法

    javascript 具有的一个特性就是异步编程。异步编程具有的优势本文不做细说,本文主要是总结如何异步编程中出现...

  • Javascript------异步编程的4种方法

    Javascript异步编程的4种方法

  • 深入了解下Promise

    Promise 意义 Promise 的诞生与 Javascript 中异步编程息息相关,js 中异步编程主要指 ...

  • JavaScript学习笔记(5) 异步-- Promise

    写在前面 异步编程对Javascript语言非常重要,在Javascript的发展道路上,异步编程的方法也是一直在...

  • AJAX入门

    AJAX(Async Javascript and Xml):在AJAX中的异步不是异步编程中的异步,而是泛指“局...

网友评论

      本文标题:JavaScript异步编程

      本文链接:https://www.haomeiwen.com/subject/fhntwftx.html