async 更優雅異步體驗

文章同步自我的博客: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 沒多大的變更,歸根結底就是個語法糖,幫助咱們運行生成器,而不須要咱們本身寫起動器了。
不過效果確實很是好,讓異步編程更加的同步了。函數

相關文章
相關標籤/搜索