使用如下:
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