异步操作——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. 深入理解异步操作

“认识generator”这篇文章中,我更多地是从迭代器的角度去看generator,我们现在从异步操作的角度来看待generator

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

执行权一直calling codegenerator函数两个地方轮换,两段代码的数据交流可以通过yield.next(data)进行交换。
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部分,我们可以用自动执行器,来让generator函数执行,比如我们可以引入模块co来完成上述calling code的操作。
也可以自己写一个自动执行器

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函数的实现原理, 就是将Generator 函数和自动执行器, 包装在一个函数里。

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);

包装函数:

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();
    });
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容