美文网首页
Javascript异步解决方案的发展历程

Javascript异步解决方案的发展历程

作者: 虎妞先生 | 来源:发表于2019-02-27 23:27 被阅读0次

    1.回调函数

    function f1(callback){
        setTimeout(function(){
            //f1的任务代码
            callback();
        },1000);
    }
    f1(f2);
    
    ajax('XXX1', () => {
        // callback 函数体
        ajax('XXX2', () => {
            // callback 函数体
            ajax('XXX3', () => {
                // callback 函数体
            })
        })
    })
    

    优点:便于理解
    缺点:回调地狱,不能捕获错误

    2.事件监听

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

    容易理解,可以绑定多个事件,每个事件可以指定多个回调函数;缺点,整个流程都要变成事件驱动型,运行流程会变得不清晰。

    3.发布/订阅(观察者模式)

    jQuery.subscribe("done", f2);
    function f1(){
        setTimeout(function () {
          // f1的任务代码
          jQuery.publish("done");
        }, 1000);
    }
    jQuery.unsubscribe("done", f2);
    

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

    4.Promises对象

    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 ,错误需要通过回调函数来捕获

    5.Generator

    特点:可以控制函数的执行,Generator函数是协程在ES6中的实现,最大的特点就是可以交出函数的执行权(即暂停执行)
    执行Generator函数后会返回一个遍历器对象(Iterator)。本质上Generator是一个状态机,每次的遍历Generator函数返回的都是函数内部的每个状态。

        function* gen() {    
            yield 1;    
            yield 2;    
            return 1;
          }
          var g = gen();
          gen.next() // {value:1,done:false}
          gen.next() // {value:2,done:false}
          gen.next() // {value:3,done:true}
    

    Generator函数是分段执行的,yield语句是暂停执行的标记,而next方法可以恢复执行。缺点还需要编写自动执行器

    6.使用async函数

    async函数的实现就是将Generator函数和自动执行器包装在一个函数中

    function async gen(){
        awiat 1;
        awiat 2;
    }
    

    异步编程的语法目标,就是怎样让它更像同步编程,使用async/await的方法,使得异步编程与同步编程看起来相差无几了。

    7.借助流程控制库

    NPM社区中出现了很多流程控制库可以供开发者直接使用,其中很流行的就是async库,该库提供了一些流程控制方法,其官方文档见http://caolan.github.io/async/docs.html
    如果需要执行的任务紧密结合。下一个任务需要上一个任务的结果做输入,应该使用瀑布式
    如果多个任务必须依次执行,而且之间没有数据交换,应该使用串行执行
    如果多个任务之间没有任何依赖,而且执行顺序没有要求,应该使用并行执行

    8.使用Web Workers

    Web Worker是HTML5新标准中新添加的一个功能,Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage。其数据交互过程也类似于事件发布/监听模式,异能实现异步操作

    9 对比

    异步读取文件

    1.回调函数

    fs.readFile(fileA,(err,data)=>{
        if(err) throw err;
        console.log(data);
        fs.readFile(fileB,(_err,_data)=>{
            if(_err) throw err;
            console.log(_data)
        })
    }
    

    2.使用Promise

    var fs = require('fs');
    var readFile = function(path) {
        return new Promise((resolve, reject) => {
            fs.readFile(path, (err, data) => {
                if (err) reject(err)
                resolve(data)
            })
        })
    }
    readFile(fileA)
    .then((data)=>{console.log(data)})
    .then(()=>{return readFile(fileB)})
    .then((data)=>{console.log(data)})
    // ... 读取n次
    .catch((err)=>{console.log(err)})
    
    

    3.使用Generator

    var fs = require('fs');
    
    var readFile = (path) => {
        return new Promise((resolve, reject) => {
            fs.readFile(path, (err, data) => {
                if (err) reject(err)
                resolve(data)
            })
        })
    }
    
    var gen = function* () {
        var f1 = yield readFile(fileA);
        var f2 = yield readFile(fileB);
        console.log(f1.toString());
        console.log(f2.toString());
    }
    gen.next()
    grn.next()
    

    4.使用Async

    var asyncReadFile = async function() {
        var f1 = await readFile(fileA);
        var f2 = await readFile(fileB);
        console.log(f1.toString())
        console.log(f2.toString())
    }
    

    相关文章

      网友评论

          本文标题:Javascript异步解决方案的发展历程

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