JS异步任务队列

https://zhuanlan.zhihu.com/p/41543963
https://juejin.im/post/59e85eebf265da430d571f89#heading-9
https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5be04a8e6fb9a04a072fd2cd

0. Event Loop

console.log('1');

setTimeout(function() {
    console.log('2');
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('3')
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('10')
    }).then(function() {
        console.log('12')
    })
})

await 执行顺序

let a = 0
let b = async () => {
  a = a + await 10
  console.log('2', a) 
}
b()
a++
console.log('1', a)
function testPromise() {
    return new Promise(resolve => {
        resolve('promise')
    })
}

async function asyncFn() {
    let res = await testPromise()
    console.log(res)
}

asyncFn()

console.log('script end')
function testPromise() {
    return 'promise'
}

async function asyncFn() {
    let res = await testPromise()
    console.log(res)
}

asyncFn()

console.log('script end')
Promise.resolve
new Promise(res => res())
function testPromise() {
  return new Promise(resolve => {
        resolve('promise')
  })
}

async function asyncFn() {
    let res = await testPromise()
    console.log(res)
}
new Promise(res => res('xxx'))
.then(res => console.log(res))
asyncFn()
console.log('script end')
async function asyncFn() {
    console.log('asyncFn')
    let res = await asyncFn2()
    console.log(res)
}

async function asyncFn2() {
    console.log('asyncFn2')
    let res = await fn3()
    console.log(res)
    return 'asyncFn2 return'
}

function fn3() {
    console.log('fn3')
}

setTimeout(() => {
    console.log('setTimeout')
}, 0)

console.log('script start')

asyncFn()

let promise = new Promise(resolve => {
    console.log('promise')
    resolve('promise resolved')
    console.log('after promise resolved')
}).then(res => {
    console.log(res)
})

console.log('script end')

对于以上代码你可能会有疑惑,让我来解释下原因

首先函数 b 先执行,在执行到 await 10 之前变量 a 还是 0,因为 await 内部实现了 generator ,generator 会保留堆栈中东西,所以这时候 a = 0 被保存了下来
因为 await 是异步操作,后来的表达式不返回 Promise 的话,就会包装成 Promise.reslove(返回值),然后会去执行函数外的同步代码
同步代码执行完毕后开始执行异步代码,将保存下来的值拿出来使用,这时候 a = 0 + 10
上述解释中提到了 await 内部实现了 generator,其实 await 就是 generator 加上 Promise 的语法糖,且内部实现了自动执行 generator。如果你熟悉 co 的话,其实自己就可以实现这样的语法糖。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  •  最近在一个项目中,遇到这么一个需求:一个页面中,大概有四五个元素需要按一定次序依次进场,setTimeout来实...
    孤丶狼丶阅读 1,301评论 0 1
  • 异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...
    呼呼哥阅读 7,336评论 5 22
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 6,400评论 9 19
  • 弄懂js异步 讲异步之前,我们必须掌握一个基础知识-event-loop。 我们知道JavaScript的一大特点...
    DCbryant阅读 2,752评论 0 5
  • 由于课程上提供的网站访问不了,就随便找了一个网站来爬地址是http://guo.lu(好像是个很文艺的网站啊XD)...
    星罹阅读 400评论 0 0