美文网首页
异步操作,promise,generator

异步操作,promise,generator

作者: 秦小婕 | 来源:发表于2017-11-13 22:49 被阅读0次

    1.js中完成异编程的方法

    • 回调函数
    • 事件监听
    • 发布订阅
    • Promise对象
      当多个回调的执行是需要按照一定顺序的时候,回调函数的方式需要进行多层嵌套。所以采用Promise的链试调用来解决这个问题

    2.Generator函数实现协成

    使用yield作为暂停标记

    3.generator的数据交换和错误处理

    使用next(argument)传参数,使用throw()进行异常or错误处理。

    4.使用generator封装异步操作

      var fetch = require('node-fetch');
    
      function* gen(){
          var url = 'https://api.github.com/users/github';
          var result = yield fetch(url);
          console.log(result.bio);
        }
    

    代码执行的方式:

       var g = gen();
       var result = g.next();
    
        result.value.then(function(data){
              return data.json();
            }).then(function(data){
                 g.next(data);
            });
    

    问题:流程管理比较麻烦,即何时执行第一阶段,何时执行第二阶段。

    5.什么是Thunk函数

    Thunk函数实现“传名调用”,将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做 Thunk 函数。
    js中的Thunk函数替换的不是表达式,而是多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数,且只接受回调函数作为参数

         // 正常版本的readFile(多参数版本)
           fs.readFile(fn, argument,callback);
    
        // ES6版本
        const Thunk = function(fn) {
            return function (...args) {
              return function (callback) {
                 return fn.call(this, ...args, callback);
                 }
              };
          };
       //函数调用方式
         var readFileThunk = Thunk(fs.readFile);
         readFileThunk(fileA)(callback);
       //相当于fn(, , ,)变为fn()()();
    

    6.generator函数的流程管理

    • 使用whil循环进行自动流程管理

      function* gen() {
         }

      var g = gen();
      var res = g.next();
      while(!res.done){
      console.log(res.value);
      res = g.next();
      }
      

    注意:不适合在异步操作中。因为不会判断何时异步操作会完成。处理方法:基于promise完成。即yield后面是promise对象。自启动也是基于promise的then()调用完成。

    • 使用Thunk函数,Thunk函数在回调函数中将执行权交还给generator函数

    • 异步操作流程管理,函数的手动执行方式

       var fs = require('fs');
       var thunkify = require('thunkify');
       var readFileThunk = thunkify(fs.readFile);
      
       var gen = function* (){
           var r1 = yield readFileThunk('/etc/fstab');
           console.log(r1.toString());
           var r2 = yield readFileThunk('/etc/shells');
           console.log(r2.toString());
       };
      

    手动方式:回调函数中调用g.next()将执行权返回给generator函数

    var g = gen();
    
    var r1 = g.next();
     r1.value(function (err, data) {
       if (err) throw err;
       var r2 = g.next(data);
       r2.value(function (err, data) {
       if (err) throw err;
       g.next(data);
      });
    });
    
    • Thunk函数的自动流程管理(不太懂)

    • 基于Promise的自启动

      var fs = require('fs');
      
      var readFile = function (fileName){
         return new Promise(function (resolve, reject){
            fs.readFile(fileName, function(error, data){
              if (error) return reject(error);
              resolve(data);
            });
         });
      };
      
      var gen = function* (){
      var f1 = yield readFile('/etc/fstab');
      var f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
      };
      

    手动方式:

      var g = gen();
    
      g.next().value.then(function(data){
        g.next(data).value.then(function(data){
           g.next(data);
        });
     });
    

    自动方式:

    function run(gen){
      var g = gen();
    
      function next(data){
        var result = g.next(data);
        if (result.done) return result.value;
        result.value.then(function(data){
          next(data);
        });
     }
      next();
    }
    run(gen);
    

    相关文章

      网友评论

          本文标题:异步操作,promise,generator

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