異步操作——generator

reference

  1. https://www.cnblogs.com/chenjinxinlove/p/8467774.html
  2. https://juejin.im/post/5b54ca8ef265da0f7e628b6f
  3. https://juejin.im/post/5a30193051882503dc53af3c#heading-13
  4. https://juejin.im/post/5bcf3e3f6fb9a05cd53b3e3d#heading-11

1. 深入理解異步操作

“認(rèn)識generator”這篇文章中,我更多地是從迭代器的角度去看generator,我們現(xiàn)在從異步操作的角度來看待generator

function* gererator(){
  //do some stuff
  yield value1;
 //do some stuff;
  yield value2;
}

執(zhí)行權(quán)一直calling codegenerator函數(shù)兩個地方輪換,兩段代碼的數(shù)據(jù)交流可以通過yield.next(data)進(jìn)行交換。
generator異步讀取文件的實例

var fs=require('fs');
var readfile=function(filename){
  return new Promise((resolve,reject=>{
    fs.readFile(filename, (error,data)=>{
        if(error) reject(new Error('whoops');
        resolve(data);
      });
  });
}
//generator
var gen=function* (){
  var file1=yield readfile('./data1.json');
  var file2= yield readfile('./data2.json');
  console.log('done');
}
//calling code
var generator=gen();
generator.next().value.then(data=>{
  generator.next(data).value.then((data)=>{
      generator.next(data);
    }
  );
});

在外層的calling code部分,我們可以用自動執(zhí)行器,來讓generator函數(shù)執(zhí)行,比如我們可以引入模塊co來完成上述calling code的操作。
也可以自己寫一個自動執(zhí)行器

function run(generator){
    var g=generator();
    function next(data){
        var result=g.next(data);
        if(result.done){
            console.log(result.value);
        }else{
            result.value.then(function(data){
                next(data);
            });
        }
    }
    next();
}

事實上,上述代碼如果asyncawait的語法來寫,就會變得非常簡潔。

async function loadFile(){
  var file1=await readfile('./data1.json');
  var file2=await readfile('/data2.json');
  console.log('done');
}

2. async函數(shù)的實現(xiàn)原理, 就是將Generator 函數(shù)和自動執(zhí)行器, 包裝在一個函數(shù)里。

function getName(name){
    return new Promise((resolve)=>{
        setTimeout(resolve(name),1000);
    });
}
function* gen(){
    let data1=yield getName('nancy');
    let data2=yield getName('bill');
    return [data1,data2];
}
function run(generator){
    return new Promise(resolve=>{
        var g=generator();
        var output;
        function next(data){
            var result=g.next(data);
            if(result.done){
                output=result.value;
                resolve(output);
            }else{
                result.value.then(function(data){
                    next(data);
                });
            }
        }
        next();
    });
}
run(gen).then(console.log); //output ['nancy','bill'].
//example:
// var fs=require('fs');
function getName(name)
{
    return new Promise(resolve=>{
        setTimeout(resolve(name),1000);
    });
}
async function readfile(name1,name2){
    let data1=await getName(`hello, ${name1}`);
    let data2=await getName(`hello, ${name2}`);
    return [data1,data2];
}
// now use promise and generator.
function* generator(name1,name2){
    let data1=yield getName(`hello, ${name1}`);
    let data2=yield getName(`hello, ${name2}`);
    return [data1,data2];
}
function wrapper(gen){
    return function(...args){
        return new Promise(resolve=>{
            var g=gen(...args);
            function next(data){
                var result=g.next(data);
                if(result.done) resolve(result.value)
                else{
                    result.value.then(data=>{
                        next(data);
                    });
                }
            }
            next();
        });
    }
}
var readfile_gen=wrapper(generator);
readfile('jason','gisele').then(console.log);
readfile_gen('jason','gisele').then(console.log);

包裝函數(shù):

const wrapAsync=function(generatorFn){
  return function(...args){
    return new Promise(resolve=>{
      var g=generatorFn(...args);
      function next(data){
        var result=g.next(data);
        if(result.done) resolve(result.value);
        else{
          result.value.then(data=>{
            next(data);
          });
        }
      }
      next();
    });
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容