Keep

Async/Await

发布:

async/await 语法让开发者用同步的代码写法方式写异步逻辑,扩展之前基于 Promise 的写法。

实例

// 下面使用 setTimeout 模拟异步请求
function sleep(n) {
  return new Promise(resolve => {
    setTimeout(resolve, n * 1000)
  })
}

// 部署两个异步接口
function get_ad_data() {
  return new Promise((resolve, reject) =>
    sleep(1).then(() =>
      (config.ad_fail ? reject : resolve)({data: '_ad_data_'})))
}

function get_article_data() {
  return new Promise((resolve, reject) =>
    sleep(2).then(() =>
      (config.article_fail ? reject : resolve)({data: '_article_data_'})))
}

// 两个请求之后的处理 - 同步渲染
function renderArticle(article, from) {
  console.log('render:', article, from, new Date)
}

function renderAd(ad, from) {
  console.log('render_ad:', ad, from, new Date)
}

// 并行
// 基于 Promise 写法
// 代码先同步执行完,等状态到 resolved 时,
// 再执行各种的 then/catch 处理
function application_promise(is_ad) {
  let request_article_promise = get_article_data()
  // 不考虑 render 异常
  let render_article_promise = request_article_promise
    .then(article => renderArticle(article, 'promise'))
    .catch(e => {
      console.log('request.catch', e, 'promise')
      return Promise.reject(e)
    })
  if (is_ad) {
    let request_ad_x_promise = get_ad_data()
    Promise.all([render_article_promise, request_ad_x_promise]).then(values => {
      let [_, ad] = values
      renderAd(ad, 'promise')
    }).catch(e => {
      console.log('catch:', e, 'promise')
    })
  }
}

// 串行
// await 语法会卡住等待第一个 Promise 状态结束
async function application_async(is_ad) {
  var article
  try {
    article = await get_article_data()
    if (article) {
      renderArticle(article, 'async')
    }
  } catch (e) {
    console.log('request.catch', e, 'async')
  }

  // article 异常时,不会再继续 (串行)
  if (is_ad && article) {
    var ad
    try {
      ad = await get_ad_data()
      if (ad) {
        renderAd(ad, 'async')
      }
    } catch (e) {
      console.log('catch:', e, 'async')
    }

  }
}

// 并行
// 让两个 promise 先行
// 使用 async/await 语法 hold 住状态
async function application_async_ex(is_ad) {
  var articlePromise = get_article_data()
  var adPromise
  if (is_ad) {
    adPromise = get_ad_data()
  }
  var article
  try {
    let [article, ad] = [
      await articlePromise,
      await adPromise
    ]
    if (article) {
      renderArticle(article, 'async_ex')
      if (ad) {
        renderAd(ad, 'async_ex')
      }
    }
  } catch (e) {
    console.log('request.catch', e, 'async_ex')
  }
}

var config = {
  ad: true,
  ad_fail: false,
  article_fail: false
}

application_promise(config.ad)
application_async(config.ad)
application_async_ex(config.ad)

avatar image

@read2025, 生活在北京(北漂),程序员,宅,马拉松[纯粹],喜欢动漫。"骑士总能救出公主,是因为恶龙从没伤害过她"