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来实...
    孤丶狼丶阅读 972评论 0 1
  • 异步编程对JavaScript语言太重要。Javascript语言的执行环境是“单线程”的,如果没有异步编程,根本...
    呼呼哥阅读 6,072评论 5 22
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 5,716评论 9 19
  • 弄懂js异步 讲异步之前,我们必须掌握一个基础知识-event-loop。 我们知道JavaScript的一大特点...
    DCbryant阅读 2,073评论 0 4
  • 由于课程上提供的网站访问不了,就随便找了一个网站来爬地址是http://guo.lu(好像是个很文艺的网站啊XD)...
    星罹阅读 168评论 0 0
  • 我有个500人的姐妹群,活跃度非常高,今天下午引起讨论的话题是——感觉自己老了。小仙女们贡献了许多心塞小句,对照看...
    鹿z有萌阅读 158评论 0 0
  • 仲裁诡计小雕虫,听到消息愤满胸。几个老妖掀恶浪,一群贼子运阴功。恨无短剑封喉断,期有长矛贯体通。华夏儿孙多警醒,应...
    雨才阅读 116评论 0 3
  • 慢慢纠正自己养成的写代码时的坏习惯
    王凯_河师大阅读 22评论 0 1
  • 本章介绍波粒二象性的相关内容,主要有能量量子化、光电粒子性、粒子的波动性、概率波以及不确定性关系等几方面。 『能量...
    物理看華阅读 1,087评论 0 0