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