Generator函数的实际应用

1.异步操作的同步化表达 function* main() { var result = yield request("http://some.url"); var resp = JSON.parse(result); console.log(resp.value); } function request(url) { makeAjaxCall(url, function(response){ it.next(response); }); } var it = main(); it.next(); 2.控制流管理 (针对同步任务) 对于层层嵌套的操作,一般写法 step1(function (value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { // Do something with value4 }); }); }); }); 使用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); } } 3.部署 Iterator 接口 对象是没有Iterator 接口的,因为Generator函数运行后返回的是一个遍历器对象,可以利用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); } 4.Generator 函数的异步应用 Generator 函数可以暂停执行和恢复执行,这是它能封装异步任务的根本原因 除此之外,它还有两个特性,使它可以作为异步编程的完整解决方案:函数体内外的数据交换和错误处理机制。 Generator 就是一个异步操作的容器。它的自动执行需要一种机制,当异步操作有了结果,能够自动交回执行权。 两种方法可以做到这一点。 (1)回调函数。将异步操作包装成 Thunk 函数,在回调函数里面交回执行权。 (2)Promise 对象。将异步操作包装成 Promise 对象,用then方法交回执行权。 4.1利用Thunk 函数 在 JavaScript 语言中,是针对多参数函数,将其替换成一个只接受回调函数作为参数的单参数函数。 Thunkify 模块 生产环境的转换器,建议使用 Thunkify 模块,来实现Thunk 函数功能。 首先安装 npm install thunkify var fs = require('fs'); var thunkify = require('thunkify'); var readFileThunk = thunkify(fs.readFile); var g = function* (){ var f1 = yield readFileThunk('fileA'); var f2 = yield readFileThunk('fileB'); // ... var fn = yield readFileThunk('fileN'); }; //执行器 function run(fn) { var gen = fn(); function next(err, data) { var result = gen.next(data); if (result.done) return; result.value(next); } next(); } run(g); 4.2go模块 co 模块可以让你不用编写 Generator 函数的执行器。 使用 co 的前提条件是,Generator 函数的yield命令后面,只能是 Thunk 函数或 Promise 对象。 var gen = function* () { var f1 = yield readFile('/etc/fstab'); var f2 = yield readFile('/etc/shells'); console.log(f1.toString()); console.log(f2.toString()); }; var co = require('co'); co(gen);

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):