编辑: 笨蛋爱傻瓜悦 2019-07-09

6 {value: xxx, done: false} 当 generator 运行到 yield 关键字时,generator 就会进入暂态.如果在调用 next 方法时传递了参数 next(param) ,则能将 param 传回 generator 流程, 这在调用异步过程时非常有用,如上面代码片中的 returnTwoAsync 、 returnThreeAsync 所示. 利用 generator 组织异步流程 假设一个业务流程中穿插了多个异步过程,除了进行传统的回调解决策略,也可借 助于 generator 进行解决,但需要做如下改造: 通过 generator 函数来组织业务流程,可以通过 yield 来等待异步流程执行 完毕,通过 try-catch 进行错误处理: function* gen() { try { let data1 = yield callback1();

catch (e) { console.error(e);

} let data2 = yield callback2();

} } // 调用generator函数,获得操纵generator执行过程的迭代器对象 const it = gen();

// 首次调用`next`方法,驱动generator开始执行 it.next() 改造异步方法: 遇到错误通过迭代器对象的 throw(error) 方法抛出错误,使得外部能够通 过 try-catch 进行错误处理. 如果没有发生错误,则可以继续业务流程,并利用传递参数的 next() 方法 告知 generator 运行结果,并继续 generator 函数的执行. 利用 generator 组织异步流程

7 function callback(err, data) { if(err) { 抛出错误 it.throw(err);

} else { it.next(data);

} } 综上,利用 generator,上一节的文件大小统计代码就可以这样撰写: 利用 generator 组织异步流程

8 const fs = require('

fs'

);

// 改造size方法 function size(filename) { fs.stat(filename, function(err, stat) { if(err) it.throw(err);

else it.next(stat.size);

});

} function *main() { const sizeInfo = { file1'

: 0, file2'

: 0, file3'

:

0 };

try { sizeInfo['

file1'

] = yield size('

file1.md'

);

sizeInfo['

file2'

] = yield size('

file2.md'

);

sizeInfo['

file3'

] = yield size('

file3.md'

);

} catch(e) { console.error(e);

} console.log(sizeInfo);

} const it = main();

// 驱动iterator运行 it.next();

可以看到,借助于 generator,我们可以用传统的阻塞式的、同步式的代码来撰写 业务逻辑,也可以通过 try-catch 进行错误处理,但是,需要进行一定程度侵 入式的改造,假设原有

100 个异步函数,我们就需要改造这

100 个函数,并且还 担心这样的改造影响到原有的业务流程,因此,我们还需要进一步的处理,首先, 我们会考虑创建一个运行器,来驱动我们的 generator 运行. 利用 generator 组织异步流程

9 执行器 上一节中,我们利用 generator,实现了以同步式代码的形式来组织异步流程,但是,如果我们有多个 generator 函数,则需要手动驱动每个 generator 的运行,而 且这些代码大体是重复的: function *gen1(){} function *gen2(){} function *gen3(){} let it1 = gen1();

let it2 = gen2();

let it3 = gen3();

it1.next();

it2.next();

it3.next();

因此,我们考虑设计一个执行器(runner),来驱动 generator 的运行: 运行器

10 /** * 运行器 * @param {Generator} generatorFunc */ function runGenerator(generatorFunc) { // 获得generator迭代器 let it = generatorFunc();

next();

/** * 自定义一个next函数 */ function next(err, res) { if (err) { it.throw(err);

下载(注:源文件不在本站服务器,都将跳转到源网站下载)
备用下载
发帖评论
相关话题
发布一个新话题