文章同步自我的博客:http://www.52cik.com/2016/07/11/generator-co.htmlhtml
上一篇《讓 Generator 自啓動》介紹了經過起動器讓 Generator 跑起來,而本篇採用 async 實現更優雅的異步編程。編程
借用上一篇例子中的例子提及。併發
function* gen() { var r1 = yield $.get('url1'); var r2 = yield $.get('url2'); var r3 = yield $.get('url3'); console.log(r1, r2, r3); }
而後,咱們須要寫一個啓動器來啓動這個函數。
而採用 async 寫,代碼則是:異步
async function gen() { var r1 = await $.get('url1'); var r2 = await $.get('url2'); var r3 = await $.get('url3'); console.log([r1, r2, r3].join('\n')); } gen(); // 直接運行便可
直接運行了,無須寫生成器來運行了,而代碼僅僅是 *
改成 async
, yield
改成 await
而已。
因此本質上講:async 就是 Generator 的語法糖。async
多任務處理有個坑,就是不能直接在 forEach
, map
之類的方法裏處理,不然會報錯或者獲得錯誤的結果。異步編程
function sleep(t) { return new Promise(resolve => setTimeout( _ => { resolve(+new Date) }, t)) } async function run() { // 順序 let a = await sleep(100) let b = await sleep(200) // 併發1 let c = await Promise.all([sleep(100), sleep(200), sleep(300)]) // 併發2 let d = await Promise.all([100, 200, 300].map(t => sleep(t))) // 併發3 let list = [sleep(100), sleep(200), sleep(300)] let e = [] for (let fn of list) { e.push(await fn) } console.log( '', 'a:', a, '\n', 'b:', b, '\n', 'c:', c, '\n', 'd:', d, '\n', 'e:', e, '\n' ) } run() // a: 1468317737179 // b: 1468317737384 // c: [ 1468317737485, 1468317737589, 1468317737688 ] // d: [ 1468317737792, 1468317737890, 1468317737989 ] // e: [ 1468317738094, 1468317738193, 1468317738293 ]
async 沒多大的變更,歸根結底就是個語法糖,幫助咱們運行生成器,而不須要咱們本身寫起動器了。
不過效果確實很是好,讓異步編程更加的同步
了。函數