es6中生成器Generator的使用场景

本文探讨了如何使用Generator函数改进控制流管理,通过Promise和Generator结合处理耗时操作,以及如何在对象上部署Iterator接口。作者还分享了如何将大型项目分解为同步步骤,以及提供了一份针对Web前端和Android开发的学习资源。
摘要由CSDN通过智能技术生成

}

上面代码打开文本文件,使用yield表达式可以手动逐行读取文件。

2、控制流管理


如果有一个多步操作非常耗时,采用回调函数,可能会写成下面这样。

step1(function (value1) {

step2(value1, function(value2) {

step3(value2, function(value3) {

step4(value3, function(value4) {

// Do something with value4

});

});

});

});

采用 Promise 改写上面的代码。

Promise.resolve(step1)

.then(step2)

.then(step3)

.then(step4)

.then(function (value4) {

// Do something with value4

}, function (error) {

// Handle any error from step1 through step4

})

.done();

上面代码已经把回调函数,改成了直线执行的形式,但是加入了大量 Promise 的语法。Generator 函数可以进一步改善代码运行流程。

function* longRunningTask(value1) {

try {

var value2 = yield step1(value1);

var value3 = yield step2(value2);

var value4 = yield step3(value3);

var value5 = yield step4(value4);

// Do something with value4

} catch (e) {

// Handle any error from step1 through step4

}

}

然后,使用一个函数,按次序自动执行所有步骤。

scheduler(longRunningTask(initialValue));

function scheduler(task) {

var taskObj = task.next(task.value);

// 如果Generator函数未结束,就继续调用

if (!taskObj.done) {

task.value = taskObj.value

scheduler(task);

}

}

注意,上面这种做法,只适合同步操作,即所有的task都必须是同步的,不能有异步操作。因为这里的代码一得到返回值,就继续往下执行,没有判断异步操作何时完成。

下面,利用for…of循环会自动依次执行yield命令的特性,提供一种更一般的控制流管理的方法。

let steps = [step1Func, step2Func, step3Func];

function *iterateSteps(steps){

for (var i=0; i< steps.length; i++){

var step = steps[i];

yield step();

}

}

上面代码中,数组steps封装了一个任务的多个步骤,Generator 函数iterateSteps则是依次为这些步骤加上yield命令。

将任务分解成步骤之后,还可以将项目分解成多个依次执行的任务。

let jobs = [job1, job2, job3];

function* iterateJobs(jobs){

for (var i=0; i< jobs.length; i++){

var job = jobs[i];

yield* iterateSteps(job.steps);

}

}

上面代码中,数组jobs封装了一个项目的多个任务,Generator 函数1iterateJobs则是依次为这些任务加上yield*命令。

最后,就可以用for…of循环一次性依次执行所有任务的所有步骤。

for (var step of iterateJobs(jobs)){

console.log(step.id);

}

再次提醒,上面的做法只能用于所有步骤都是同步操作的情况,不能有异步操作的步骤。

for…of的本质是一个while循环,所以上面的代码实质上执行的是下面的逻辑。

var it = iterateJobs(jobs);

var res = it.next();

while (!res.done){

var result = res.value;

// …

res = it.next();

}

3、部署 Iterator 接口


利用 Generator 函数,可以在任意对象上部署 Iterator 接口。

function* iterEntries(obj) {

let keys = Object.keys(obj);

for (let i=0; i < keys.length; i++) {

let key = keys[i];

yield [key, obj[key]];

}

}

let myObj = { foo: 3, bar: 7 };

for (let [key, value] of iterEntries(myObj)) {

console.log(key, value);

}

// foo 3

// bar 7

上述代码中,myObj是一个普通对象,通过iterEntries函数,就有了 Iterator 接口。也就是说,可以在任意对象上部署next方法。

下面是一个对数组部署 Iterator 接口的例子,尽管数组原生具有这个接口。

function* makeSimpleGenerator(array){

var nextIndex = 0;

while(nextIndex < array.length){

yield array[nextIndex++];

}

}

var gen = makeSimpleGenerator([‘yo’, ‘ya’]);

gen.next().value // ‘yo’

gen.next().value // ‘ya’

gen.next().done // true

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

[外链图片转存中…(img-MpGaC9bR-1714854934268)]

[外链图片转存中…(img-H1BStosu-1714854934268)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值