关于小程序 async await

我page modify.js引入了

import regeneratorRuntime from '../../utils/wxPromise.min.js';

在onReady执行了异步 等待操作

  async onReady(){  

      await this.testawait();

      console.log("test");   

  },

testawait方法为一个setTimeout异步操作

  testawait(){
      setTimeout(function(){ console.log("await-aftrt-consolelog")}, 3000);
  },

按我的理解控制台应该是先执行完await的testawait方法在执行后面的打印console.log("test");

但是控制台打印出的信息却是先打印console.log("test");然后在执行testawait方法。这是什么原因导致的?

image

阅读 2.4k
4 个回答
testawait(){
  return new Promise(resolve => setTimeout(function(){ console.log("await-aftrt-consolelog"); resolve()}, 3000));
}

大家不推荐跳过 ES5 直接学 ES6 的原因:如果不先理解 Promise,直接学 async-await 的话,就容易以为 await 会自动包装异步操作
实际上 await 只能“等待” Promise 传递给 resolve 函数的参数,如果await后面一个表达式的值不是一个 Promise 的话,“等来”的其实是该表达式的值,对于 testawait() 而言,就是一个 undefined,其中的异步过程该怎么进行还怎么进行。


所以,要想按照你的预期运行的话,testawait可以改成:

 testawait(){
    return new Promise((resolve) => {
        setTimeout(function(){ 
            console.log("await-aftrt-consolelog");
            resolve('什么鬼');  // await 到的是这个字符串
        }, 3000);
    })
  }

问题应该在setTimeout上,setTimeout是异步操作,由于setTimeout是异步所以会继续执行后面的内容,所以此处应该是执行过了testawait中的内容的。

新手上路,请多包涵

js的事件队列机制,上面的代码等于

async onReady(){
        Promise.resolve(this.testawait()).then(()=>{
        console.log('test')
    })
},

await是一个让出线程的标志,它后面的表达式this.testawait()会先执行一遍,this.testawait()中是一个宏任setTimeout,所以将setTimeout放入宏任务队列中,然后将await后面的代码console.log('test')放到微任务队列中,执行栈中的任务全部执行完毕,然后清空微任务队列中的console.log('test'),第一轮Event Loop执行完,再把宏任务队列中的任务加入到执行栈中开始第二轮的Event Loop,所以是先输出'test',再输出'await-aftrt-consolelog'

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题