使用如下:
function *foo(len,urlArray) {let r = [];for(let i =0; i< len; i++){r[i] = yield request(urlArray[i]);}
}
// len:是长度,urlArray,是请求的url数组..
下面附上run函数的代码,以及证明以上是成立的
// Benjamin Gruenbaum(@benjamingr on Github)
function run(gen) {var args = [].slice.call(arguments, 1), it;it = gen.apply(this, args);return Promise.resovle().then(function handleNext(value) {var next = it.next(value);return (function handleResult(next) {if( next.done) {return next.value;} else{return Promise.resolve(next.value).then(handleNext,function handleErr(err) {return Promise.resolve(it.throw(err)).then(handleResult);}};}})(next);});
}
// emmmm,这个run我是没有看懂的,也不想检查有没有打错....其实我想说的是..利用Promise并发.
考察下面函数:
function *foo(){var r1 = yield request("http://some.url.1");var r2 = yield request("http://some.url.2");var r3 = yield request("http://some.url.3/?v=" + r1 + "," + r2);console.log(r3);
}
run(foo);
// 以上2个ajax请求是依此进行的.即:r1完成后,r2开始...
// 高效的程序是让r1和r2同时进行(并发)
// 改写如下:
function *foo(){var p1 = request("http://some.url.1");var p2 = request("http://some.url.2");var r1 = yield p1;var r2 = yield p2;var r3 = yield request("http://some.url.3/?v=" + r1 + "," + r2);console.log(r3);
}
run(foo);// 同时发出2个ajax请求.使用yield语句等待promise的决议.
这个也很像Promise.all方法
function *foo(){var results = yield Promise.all([request("http://some.url.1"),request("http://some.url.2")]);var r1 = results[0];var r2 = results[1];var r3 = yield request("http://some.url.3/?v=" +r1 + "," +r2);console.log(r3);
} run(foo);
更理想的情况是,我们希望使用bar()给我们结果(通过yield来等待),而不关心底层到底是使用Promise.all还是Promise.
function bar(url1, url2) {return Promise.all([request(url1),request(url2)]);
}function *foo(){var results = yield bar("http://some.url.1","http://some.url.2");var r1 = results[0];var r2 = results[1];var r3 = yield request("http://some.url.3/?v=" + r1 + "," + r2);console.log(r3);
}
run(foo);
// 使用bar将Promise层封装起来,不需要关心底层的实现.
// 如果将Promise直接放在生成器内部的话,在高层次的任务表达中逻辑会变得混乱
参考《你不知道的JavaScript》(中卷)P256~P261