生动形象解密Promise、Generator 函数、Async 函数三者之间的关系(下)

博客: https://blog.csdn.net/qtfying
掘金: https://juejin.im/user/57739929c4c9710055376671
QQ: 2811132560
邮箱: qtfying@gamil.com

咱们书接上回,聊到哪了来着,奥,Generate的遍历~~~
没有看到上篇的文章,来来来,我带你传送
生动形象解密Promise、Generator 函数、Async 函数三者之间的关系(上)

Generator

for … of

next()方法会执行generator的代码,然后,每次遇到yield x;就返回一个对象{value: x, done: true/false},然后“暂停”。返回的value就是yield的返回值,done表示这个generator是否已经执行结束了。如果done为true,则value就是return的返回值。

当执行到done为true时,这个generator对象就已经全部执行完毕,不要再继续调用next()了,此时也不需要我们自己判断done。

而如果用for … of可以对Generator进行遍历,自动循环遍历 Generator 函数运行时生成的Iterator对象,并且此时不再需要调用next方法

function* foo() {
  yield 1;
  yield 2;
  yield 3;
  yield 4;
  yield 5;
  return 6;
}

for (let v of foo()) {
  console.log(v);
}
// 1 2 3 4 5

上面代码使用for…of循环,依次显示 5 个yield表达式的值。这里需要注意,一旦next方法的返回对象的done属性为true,for…of循环就会中止,且不包含该返回对象,所以上面代码的return语句返回的6,不包括在for…of循环之中。

作用

generator和普通函数相比,有什么用?

从上面的例子中我们看的出来,就是把异步回调代码变成“同步”代码,天然的适合ajax请求,等我贴下代码来对比他们的区别:

我们最原始的写法是这样的

ajax('http://url-1', data1, function (err, result) {
    if (err) {
        return handle(err);
    }
    ajax('http://url-2', data2, function (err, result) {
        if (err) {
            return handle(err);
        }
        ajax('http://url-3', data3, function (err, result) {
            if (err) {
                return handle(err);
            }
            return success(result);
        });
    });
});

用到Promise来实现请求可以上一篇文章的具体示例:
生动形象解密Promise、Generator 函数、Async 函数三者之间的关系(上)
如果嫌烦,姑且就贴出一段试试,加深理解:

let promise = new Promise((resolve,reject) => {
    ajax('第一个请求').success(function(res){
        resolve(res);
    })
})
promise.then(res => {
    return new Promise((resovle,reject) => {
        ajax('second').success(function(res){
            resolve(res)
        })
    })
}).then(res => {
    return new Promise((resovle,reject) => {
        ajax('第二个请求').success(function(res){
            resolve(res)
        })
    })
}).then(res => {
    // 串行完毕你要做的xxx可以开始了
})

而用Generator怎么来做这样事情的呢?

function* ajax {
  try {
    r1 = yield ajax('http://url-1', data1);
    r2 = yield ajax('http://url-2', data2);
    r3 = yield ajax('http://url-3', data3);
    success(r3);
  }
  catch (err) {
      handle(err);
  }
}

生命奔腾不息,技术更新不止,技术的一切更新难道不是更好的服务我们吗?

如果你还要对Generator有更深的了解,姑且移步至:
廖雪峰对Generator的总结
阮一峰对Generator的总结

async/wait

Generator函数是将函数分步骤阻塞,只有主动调用next() 才能进行下一步,async函数就相当于自执行的Generator函数,相当于自带一个状态机,在await的部分等待返回, 返回后自动执行下一步。

async/wait用法

网上有种说法,是烁async/wait是相当于Generate 把“*“变成了async 把 yield 变成了 await ???😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁😁
怎么说呢,既然这样说了,我认为还是有一定得道理的,但是不至于设计的初衷就是换了个写法,要不然ECMA那些专家岂不是那个地方有点疼吗😁😁

咱们用有个例子来展示async/wait的使用方法:

async function fun (x){
    const a = await x + 1;
    await a;
}

和Generator的异同

这里咱们可以看到,相比于Generator确实很像,但是有区别:

  • 将*转为async,并且至于function最前
  • 将yield转为awiat,并且不再return
  • await后返回的是Promise对象,需要.then获取拿出,而Generator的return出具体的结果

刚刚说Generator把异步回调代码变成“同步”代码,天然的适合ajax请求,而async/wait作为Generator的语法糖,将这种“同步”发挥到了极致,在处理多个循环嵌套的时候,和Generator一样,将我们从回调的深渊中解救出来
写这边完整,查阅了很多的资料,我将下段代码直接贴出来,看到的仁兄不要介意,来展示一个Async函数的具体是怎么来处理这件事情的:

const fun1 = () => {
    return new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('fun1');
        console.log('fun1');
      },1000)
    })
  }

  const fun2 = () => {
    return new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('fun2');
        console.log('fun2');
      },1000)
    })
  }

  const fun3 = () => {
    return new Promise((resolve, reject)=>{
      setTimeout(()=>{
        resolve('fun3');
        console.log('fun3');
      },1000)
    })
  }

  async function runAll () {
    await fun1();
    await fun2();
    await fun3();
  }

  runAll().then()
          .catch()

哇塞,看到这段代码,是不是再也没有那些令人恶心的循环嵌套,再也没有像Generator那种星号(*)都出来的奇葩写法,其实技术难道不和人一样,脱俗与新颖,而又终于平常,我们可以遇到的未来是async/wait必将在以后的开发中大放异彩,尽情的享受新技术带来的震撼吧

总结

关于异步处理,如果说ES5的回调使我们陷入地狱,ES6的Promise使我们脱离魔障,终于、ES7的async-await带我们走向光明

技术像时间的巨轮,永不停止的向前滚去,而我们要做的就是永葆一颗学习的心,去不断得探索,去学习,热爱自己的工作,不锲于自己的未来

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值