zoukankan      html  css  js  c++  java
  • ES6 |Generator函数的异步应用

    在这里插入图片描述

    协程

    多个线程互相协作,完成异步任务。yield命令表示执行到此处,执行权将交给其他协程,也就是说,yield命令是异步两个阶段的分界线。协程遇到yield命令就暂停,等到执行权返回,再从暂停的地方继续往后执行。

    function *asyncJob() {
      // ...其他代码
      var f = yield readFile(fileA);
      // ...其他代码
    }
    

    Generator 函数实现协程

    function* gen(x) {
      var y = yield x + 2;
      return y;
    }
    
    var g = gen(1);	//返回一个遍历器对象 不返回结果
    //指向yield并执行,value是后面表达式的值。next方法的作用是分阶段执行Generator函数
    g.next() // { value: 3, done: false }	
    g.next() // { value: undefined, done: true }
    

    Generator 函数的数据交换和错误处理

    • next接受参数进行数据交换
      next返回值的value属性,是 Generator 函数向外输出数据;next方法还可以接受参数,向 Generator 函数体内输入数据。next接受的参数会被当做上一个yield的返回结果

      function* gen(x) {
        var y = yield x + 2;
        return y;
      }
      
      var g = gen(1);	
      g.next() // { value: 3, done: false }	
      g.next(2) // { value: undefined, done: true } 
      //在这里传入的2会被当做是上一个yield的返回结果,即yield x+2等于2,这个时候y=2并返回
      
    • 错误处理

      Generator 函数体外,使用指针对象的throw方法抛出的错误,可以被函数体内的try...catch代码块捕获

      function* gen(x){
        try {
          var y = yield x + 2;
        } catch (e){
          console.log(e);
        }
        return y;
      }
      
      var g = gen(1);
      g.next();
      g.throw('出错了');
      // 出错了
      

    异步任务的封装

    var fetch = require('node-fetch');
    
    function* gen(){
      var url = 'https://api.github.com/users/github';
      var result = yield fetch(url); //fetch读取接口,返回一个 Promise 对象
      console.log(result.bio);
    }
    
    var g = gen();
    var result = g.next();	//执行fetch(url),返回具有value和done属性的result对象
    
    //在这里value相当于fetch返回的Promise对象,data就是接口返回的结果
    result.value.then(function(data){	
      return data.json();
    }).then(function(data){
      g.next(data);
    });
    

    Thunk 函数

    背景:函数参数的求值策略

    var x = 1;
    function f(m){
      return m * 2;
    }
    f(x + 5)
    
    //1. 传值调用
    在进入函数体前就先计算x+5,成f(6),6再传进去执行,即6*2
    //2. 传名调用
    直接将表达式x+5传入,即(x+5)*2
    

    Thunk 函数的含义

    Thunk 函数是自动执行 Generator 函数的一种方法。编译器的“传名调用”实现,往往是将参数放到一个临时函数之中,再将这个临时函数传入函数体。这个临时函数就叫做 Thunk 函数

    function f(m) {
      return m * 2;
    }
    
    f(x + 5);
    // 等同于 
    var thunk = function () {
      return x + 5;
    };//相当于参数被替换成一个函数
    
    function f(thunk) {
      return thunk() * 2;
    }
    

    任何函数,只要参数有回调函数,就能写成 Thunk 函数的形式。下面是一个简单的 Thunk 函数转换器

    function f(a, cb) {
      cb(a);
    }
    let ft = Thunk(f);	//转交给Thunk暂存
    
    let log = console.log.bind(console);	//会作为表达式放进去而不会立即执行
    ft(1)(log) // 1	
    

    Thunkify 模块

    生产环境的转换器,建议使用 Thunkify 模块。首先安装模块

    $ npm install thunkify
    

    使用

    var thunkify = require('thunkify');
    var fs = require('fs');
    
    var read = thunkify(fs.readFile);
    read('package.json')(function(err, str){
      // ...
    });
    

    co模块

    用于 Generator 函数的自动执行,

    这个 Generator 函数用于依次读取两个文件

    var gen = function* () {
      var f1 = yield readFile('/etc/fstab');
      var f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    

    co 模块可以让你不用编写 Generator 函数的执行器

    var co = require('co');
    co(gen);
    

    co函数返回一个Promise对象,因此可以用then方法添加回调函数

    co(gen).then(function (){
      console.log('Generator 函数执行完成');
    });
    
  • 相关阅读:
    三种空格unicode(u00A0,u0020,u3000)表示的区别
    python调用C++之pybind11入门(相互调用)
    基于go手动写个转发代理服务
    git rebase VS git merge
    外挂
    C#本地修改器
    C# 人工智能开源库生物特征
    深层信念网络
    ASP.NET CORE(C#)与Spring Boot MVC(JAVA)
    Net UI Spy工具:ManagedSpy
  • 原文地址:https://www.cnblogs.com/sanhuamao/p/13595780.html
Copyright © 2011-2022 走看看