前端异步解决方案-4.1(generator)

媒介

终究最先写generator了,离这个系列的闭幕又进了一步。实在generator我还处在会用然则不明白道理的状况,然则学问不总结,不纪录的话轻易遗忘,所以我照样把如今的一点心得纪录下来。比及今后有了更深的明白再回来补充。
想要看更深度剖析generator的朋侪能够移步漫话JavaScript与异步·第三话——Generator:化异步为同步这里面谈及了generator的底层完成及generator的用法。是我看过的文章中自认为诠释的最好的一篇,而且篇幅也不长,发起人人去看一看。

完成

依据一向的风格,我们先尝试本身完成generator
尝试ing…………
好了尝试完了,完成不了,老老实实的进修generator的用法吧。

用法

在我的明白中,generator最大的特征就是能够让函数在特定的处所停下,守候被叫醒后在函数内部环境中继承实行。我们连系代码来看一看:
解释:【1】Iterator Object对象:参考 Iterator 文章比较长,然则假如只是想要相识什么是Iterator Object的话看完第一小节就足够了

//输出分割线的函数,感兴趣的能够自行百度怎样设置console.log的款式
function cut_off(color) {
  console.log("%c------------------------------------------","color:"+color+";font-size:20px");
}

//* 为generator函数的标识,假如我们想要建立一个generator函数就必需在function背面加上*
function* generator() {
  let num1, num2;
  num1 = 123;
  console.log("num1", num1, "num2", num2);
  //yield就是该函数内部停息的处所,停息的同时会把yield背面的值返回出去
  yield num1;
  num2 = 456;
  console.log("num1", num1, "num2", num2);
  yield num2;
  console.log("num1", num1, "num2", num2);
  return "end"
}

console.log("generator defined");
//函数返回一个Iterator Object对象;
// 然则与一般函数差别的是,这个时刻函数并不实行函数内部的代码
let g = generator();
console.log("g defined");
cut_off("red");

console.log("g.next() run 1");
//最先实行函数内部的代码,而且遇在到yield的时刻返回 yield背面的值
console.log(g.next());
cut_off("red");

console.log("g.next() run 2");
//从上次实行完的处所实行,而且遇在到yield的时刻返回 yield背面的值
console.log(g.next());
cut_off("red");

console.log("g.next() run 3");
//从上次实行完的处所实行,此次是末了一次有值的返回,done的状况会变成true
console.log(g.next());
cut_off("red");

console.log("g.next() run 4");
//已实行完成以后再次被挪用,永久返回{value:undefined, done: true}
console.log(g.next());
cut_off("red");

console.log("g.next() run 5");
//已实行完成以后再次被挪用,永久返回{value:undefined, done: true}
console.log(g.next());

贴上一张代码和运转效果的对照图辅佐人人明白
《前端异步解决方案-4.1(generator)》
愿望人人看到这里已明白了generator的基本用法,然则这个东西确切有点难,所以我放出联系方式《前端异步解决方案-4.1(generator)》
我有空的时刻能够一同讨论一下

接下来我要讲generator最主要的第二个特征,我们能够经由过程.next(value)yeild赋值(这是不正确的说法,然则我们能够这么明白,轻易我们运用generator),照样贴代码:

function* generator() {
  //第一次挪用.next()是启动了这个函数一向运转到下一个yield的位置
  let num1, num2;
  num1 = 123;
  console.log("num1", num1, "num2", num2);
  num2 = yield num1;/*1.由于运算的递次,js会先盘算右侧的值,也就是在num2被赋值之前,函数就住手运转了
                      2.第二次挪用.next(value)的时刻,value被next传入了yield的位置
                      3.顺序继承运转,value被赋值给了num2
                     */
  console.log("num1", num1, "num2", num2);
  return num2
}

let g = generator();

console.log("g.next() run 1");
console.log(g.next());
cut_off("red");

console.log("g.next(789) run 2");
//从上次实行完的处所实行,而且将789传入函数内部
console.log(g.next(789));

贴出函数和运转效果的对照图,辅佐人人明白.next(value)为yeild赋值(该说法并不正确)
《前端异步解决方案-4.1(generator)》
generator的基本进修到这里就可以尝试实际运用了,接下来我们尝试让generator在异步中大展技艺吧,话不多说上代码;

//模仿异步要求
let request = function (sucF, errF) {
  if ((sucF && typeof sucF !== "function") || (errF && typeof errF !== "function")) {
    throw new Error("传入参数必需为函数")
  }
  setTimeout(function () {
    let data = parseInt(Math.random() * 100);
    if (data < 90 && sucF) {
      sucF(data)
    } else if (errF) {
      errF("本次异步失利了")
    }
  }, 100)
};

function* generator() {
  let num1, num2;
  num1 = yield request((data) => {
    g.next(data)                 //这个处所能够有些难以明白,为何在g被建立之前,就被运用了。
  }, err => {                   //这个题目能够看解释【1】来辅佐明白
    console.error(err);
    g.return(err)               //跳过一切的yield,return直接返回err
  });
  console.log("num1", num1, "num2", num2);
  num2 = yield  request((data) => {
    g.next(data)
  }, err => {
    console.error(err);
    g.return(err)             //跳过一切的yield,return直接返回err
  });
  console.log("num1", num1, "num2", num2);
  return num2
}

let g = generator();
//启动
g.next();

解释【1】:为了诠释g为何能够在被建立之前就‘被挪用’

//实在在运转generator的时刻generator内部的代码块并没有最先运转,而是返回了一个Iterator对象,所以人人能够如许简朴明白
//function* generator 相当于 
function generator(){
    let obj = {};
    obj.next=function(){
        console.log(g);
    };
    return obj
}
//如许在挪用generator()的时刻,g不会被运用
let g = generator();
//这个时刻g被挪用了,然则在上一行代码中,g已被定义了,所以没有题目,不会报错
g.next()

这篇文章临时写到这里,由于我的页面最先卡了,所以我把generator和promise连系的用法放到下一篇文章中去;(ps:本日就会写出来的)

    原文作者:胡晓峰
    原文地址: https://segmentfault.com/a/1190000018903734
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞