ES8中,异步的最终解决方案,是Generator和promise的语法糖,以同步的形式编写异步代码

  1. async asyncFunction (params) {
  2. const data = await promiseFunc(params)
  3. return data
  4. }
  5. asyncFunction()

async函数

用async关键字修饰一个函数,修饰后叫作async函数

  1. async function asyncFunc (value) {
  2. if ( value === 'promise' ) {
  3. return Promise.reject(777)
  4. }
  5. if ( value === 'other' ) {
  6. return value
  7. }
  8. throw new Error('错了')
  9. }
  • async函数的返回值是一个promise,状态和值由函数执行结果决定
    • 返回promise:直接使用该promise的状态和值
    • 返回非promise:状态变为fulfilled,值为return的结果
    • 抛出错误:没有捕获,状态变为rejected,值为错误信息
  • async的执行时同步的,但是遇到await时,会暂停执行等待promise的结果(Generator)

await关键字

await右边是一个表达式,用来等待一个promise,只能在async函数中使用

  1. const test = value => value
  2. async function asyncFunc () {
  3. const result1 = await promise.resolve(777) // result1 === 1
  4. const result2 = await ( 7 + 1 ) // result2 === 8
  5. const result3 = await test(9) // result3 === 9
  6. }
  • await右边可以是任意表达式,并返回不同结果
    • 是promise:返回promise成功状态的结果
    • 不是promise:直接返回这个表达式的结果

执行流程

  1. 开始同步执行代码,遇到await时,先执行完await右边的表达式,然后中断函数,释放线程
  2. await会根据表达式的结果,将await表达式进行替换,然后将剩余代码放入微队列中
    • 等待的promise:继续等待,当状态发生改变后再进行操作
    • 成功的promise:替换为promise的结果
    • 失败的promise:替换为错误抛出语句,错误信息是promise的结果
    • 非promise:替换为该结果
  3. 就是根据结果创建一个promise,并在对应回调中调用 generator.next/throw()

错误处理

  1. async asyncFunction (params) {
  2. try {
  3. const data = await Promise.reject(params)
  4. return data
  5. } catch (err) {
  6. console.log('出错了')
  7. }
  8. }
  • async函数中可以直接通过 try...catch... 捕获错误,进行处理

模拟实现

async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里

  • async就是Generator,await就是yeild ```javascript async function fn(args) { // … }

// 等同于

function fn(args) { return spawn(function* () { // … }); }

  1. - 所有的async函数都能写成第二种形式,而spawn就是自动执行器
  2. ```javascript
  3. function spawn(genF) {
  4. return new Promise(function(resolve, reject) {
  5. const gen = genF();
  6. function step(nextF) {
  7. let next;
  8. try {
  9. next = nextF();
  10. } catch(e) {
  11. return reject(e);
  12. }
  13. if(next.done) {
  14. return resolve(next.value);
  15. }
  16. Promise.resolve(next.value).then(function(v) {
  17. step(function() { return gen.next(v); });
  18. }, function(e) {
  19. step(function() { return gen.throw(e); });
  20. });
  21. }
  22. step(function() { return gen.next(undefined); });
  23. });
  24. }