json yeid_异步无处不在:Generator 异步方案(五)

关于异步的知识点,终于要结束了!

本篇就来重点说说如何将 Generator 写进异步中。

Generator 异步方案

将调用 ajax 的代码写到生成器函数的 yield 后面,每次的异步执行,都要在 yield 中暂停,调用的返回结果是一个 Promise 对象。

我们可以从迭代器对象的 value 属性获取到 Promise 对象,然后使用 .then 进行链式调用处理异步结果。

结果处理的代码叫做执行器,就是具体负责运行逻辑的代码。function ajax(url) {

……

}

// 声明一个生成器函数

function * fun(){

yield myAjax('./d1.json')

yield myAjax('./d2.json')

yield myAjax('./d3.json')

}

// 返回 遍历器对象

var f = fun();

// 生成器函数的执行器

// 调用 next 方法,执行异步代码

var g = f.next();

g.value.then(data=>{

console.log(data);

// console.log(f.next());

g = f.next();

g.value.then(data=>{

console.log(data)

// g.......

})

})复制代码

而执行器的逻辑中,是相同嵌套的,因此可以写成递归的方式对执行器进行改造:// 声明一个生成器函数

function * fun(){

yield myAjax('./d1.json')

yield myAjax('./d2.json')

yield myAjax('./d3.json')

}

// 返回 遍历器对象

var f = fun();

// 递归方式 封装

// 生成器函数的执行器

function handle(res){

if(res.done) return;

res.value.then(data=>{

console.log(data)

handle(f.next())

})

}

handle(f.next());复制代码

然后,再将执行的逻辑,进行封装复用,形成独立的函数模块。function co(fun) {

// 返回 遍历器对象

var f = fun();

// 递归方式 封装

// 生成器函数的执行器

function handle(res) {

if (res.done) return;

res.value.then(data => {

console.log(data)

handle(f.next())

})

}

handle(f.next());

}

co(fun);复制代码

封装完成后,我们再使用时只需要关注 Generator 中的 yield 部分就行了。function co(fun) {

……

}

function * fun(){

yield myAjax('./d1.json')

yield myAjax('./d2.json')

yield myAjax('./d3.json')

}复制代码

此时你会发现,使用 Generator 封装后,异步的调用就变得非常简单了。

但是,这个封装还是有点麻烦,有大神帮我们做了这个封装,相当强大:github.com/tj/co ,感兴趣可以研究一下。

而随着 JS 语言的发展,更多的人希望类似 co 模块的封装能够写进语言标准中,而我们直接使用这个语法规则就行了。

其实你也可以对比一下,使用 co 模块后的 Generator 和 async 这两段代码://  async / await

async function callAjax(){

var a = await myAjax('./d1.json')

console.log(a);

var b = await myAjax('./d2.json');

console.log(b)

var c = await myAjax('./d3.json');

console.log(c)

}

// 使用 co 模块后的 Generator

function * fun(){

yield myAjax('./d1.json')

yield myAjax('./d2.json')

yield myAjax('./d3.json')

}复制代码

你应该也发现了,async 函数就是 Generator 语法糖,不需要自己再去实现 co 执行器函数或者安装 co 模块。

写法上将 * 星号去掉换成放在函数前面的 async,把函数体的 yield 去掉,换成 await。

简直完美!async function callAjax(){

var a = await myAjax('./d1.json')

console.log(a);

var b = await myAjax('./d2.json');

console.log(b)

var c = await myAjax('./d3.json');

console.log(c)

}

callAjax();复制代码

我们再来看一下 Generator。

相信下面的代码,你能很轻松地阅读。function * f1(){

console.log(11)

yield 2;

console.log('333')

yield 4;

console.log('555')

}

var g = f1();

g.next();

console.log(666);

g.next();

console.log(777);复制代码

代码运行结果:

07ddfc4d57d2409796bbc7df0668735e.png

带着 Generator 的思路,我们再回头看看那个 async 的面试题。

请写出以下代码的运行结果:setTimeout(function () {

console.log('setTimeout')

}, 0)

async function async1() {

console.log('async1 start')

await async2();

console.log('async1 end')

}

async function async2() {

console.log('async2')

}

console.log('script start')

async1();

console.log('script end')复制代码

运行结果:

a90dc3a4a0aab21c5a5976ce6107f228.png

是不是恍然大明白呢(●'◡'●)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的公寓报修管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本公寓报修管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此公寓报修管理系统利用当下成熟完善的Spring Boot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的MySQL数据库进行程序开发。公寓报修管理系统有管理员,住户,维修人员。管理员可以管理住户信息和维修人员信息,可以审核维修人员的请假信息,住户可以申请维修,可以对维修结果评价,维修人员负责住户提交的维修信息,也可以请假。公寓报修管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:公寓报修管理系统;Spring Boot框架;MySQL;自动化;VUE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值