程序员

Generator异步方案、AsyncAwait语法糖

2021-01-06  本文已影响0人  翔子丶
生成器函数(Generator)

generator是一个函数,有两个特征:generatorfunction*定义,并且除了return语句,还可以用yield返回多次

function* helloWorldGenerator() {
  yield 'hello';
  yield 'world';
  return 'ending';
}

var hw = helloWorldGenerator(); // elloWorldGenerator {<suspended>}

直接调用Generator函数,返回一个指向内部状态的指针对象;必须调用遍历器对象的next方法,使指针状态移动

yeild表达式暂停执行的标记,next方法可以恢复执行

hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }  // done属性为false 表示遍历没有完成
hw.next()
// { value: ending, done: true } // done属性为true 表示遍历已经完成
hw.next()
// { value: undefined, done: true }
Async/Await函数

async函数将generator函数的星号(*)替换为async,将yeild替换为await

async函数返回为Promise对象,使用then方法添加回调函数;函数执行一旦遇到await就先返回,等待异步操作完成,再接着执行函数体内后面的语句

async/awaitgenerator的语法糖,将generator函数和自动执行器,包装在一个函数里

function co (generator) {
    const g = generator()
    function handleResult(result) {
    if (result.down) return // 生成器函数结束
        result.value.then(data = > {
            // 递归调用直到执行完毕
            handleResult(g.next(data))
        }, error => g.throw(error))
    }
    handleResult(g.next())
}
function *main() {
    try {
     const users = yield ajax('/api/users.json')
    console.log(users)

    const posts = yield ajax('/api/posts.json')
    console.log(posts)

    const urls = yield ajax('/api/urls.json')
    console.log(urls)
  } catch (e) {
    console.log(e)
  }
}
co(main)
async function main() {
  try {
    const users = await ajax('/api/users.json')
    console.log(users)

    const posts = await ajax('/api/posts.json')
    console.log(posts)

    const urls = await ajax('/api/urls.json')
    console.log(urls)
  } catch (e) {
    console.log(e)
  }
}
const promise = main()
promise.then(() => {
  console.log('all completed')
})

使用注意:

function ajax(url) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest()
    xhr.open('GET', url)
    xhr.responseType = 'json'
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response)
      } else {
        reject(new Error(xhr.statusText))
      }
    }
    xhr.send()
  })
}
async function main() {
  try {
    const users = await ajax('/api/users.json')
    console.log(users)

    const posts = await ajax('/api/posts.json')
    console.log(posts)

    const urls = await ajax('/api/urls.json')
    console.log(urls)
  } catch (e) {
    console.log(e)
  }
}

asyncPromisegenerator相比实现最简洁,最符合语义

上一篇下一篇

猜你喜欢

热点阅读