Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

编程题:以下输出顺序多少 (setTimeout 与 promise 顺序) #120

Open
sisterAn opened this issue Oct 25, 2020 · 6 comments
Open

Comments

@sisterAn
Copy link
Owner

sisterAn commented Oct 25, 2020

setTimeout(() => console.log(0))
new Promise((resolve) => {
  console.log(1)
  resolve(2)
  console.log(3)
}).then(o => console.log(o))

new Promise(resolve => {
  console.log(4)
  resolve(5)
}).then(o => console.log(o)).then(() => console.log(6))

可参考 从一道面试题谈谈对 EventLoop 的理解

@qq1226685735
Copy link

1 3 4 2 5 6 0

@WindyWTH
Copy link

1 3 4 2 5 6 0

@qianbaiduhai
Copy link

qianbaiduhai commented Oct 26, 2020

javascript明明是单线程同步语言,但是却能实现异步效果,什么原因呢?
这是因为其通过事件循环,把代码运行中的任务分为了宏任务以及微任务。
在执行下一次事件循环之前会先把当前的微任务队列执行清空,再把宏任务队列执行清空。
首先你需要知道的是setTimeout产生的是宏任务,promise 产生的是微任务。
之后我们观看代码知道
微任务队列:['promise1', 'promise2'],宏任务队列:['setTimeout']
执行promise1,打印#1,在微任务队列里推进promise1Resolve,打印#3
微任务队列:['promise2', 'promise1Resolve'],宏任务队列:['setTimeout']
执行promise2,打印#4,在微任务队列里推进promise2Resolve
微任务队列:[ 'promise1Resolve', 'promise2Resolve'],宏任务队列:['setTimeout']
执行promise1Resolve,打印#2
执行promise2Resolve,打印#5,在微任务队列里推进promise2ResolveThen
微任务队列:['promise2ResolveThen'],宏任务队列:['setTimeout']
执行promise2ResolveThen,打印#6
微任务队列:[],宏任务队列:['setTimeout']
执行setTimeout,打印#0

更详细的了解宏微任务可以点这里

@allenlongbaobao
Copy link

@qianbaiduhai new Promise((resolve) => { console.log('1') }) 中的语句是同步语句,会立即执行的,不会放入微任务队列,resolve 之后才会进队列。可以在两个 promise 之间放一个 log 看看

@xllpiupiu
Copy link

/**
 * 1. 分析以下程序段的输出顺序
 * 主要是考察微任务 宏任务
 */
setTimeout(()=>console.log(0))
new Promise((resolve)=>{
    console.log(1)
    resolve(2)
    console.log(3)
}).then(res=>console.log(res))
new Promise((resolve)=>{
    console.log(4)
    resolve(5)
}).then(res=>console.log(res)).then(()=>console.log(6))
console.log(8)
Promise.resolve(7).then(res=>console.log(res))
/**
 * 分析:1 3 4 2 5 6 0
 * 1. setTimeout放到宏任务队列
 * 2. 立即执行new Promise 1 3  then放到微任务队列
 * 3. 立即执行new Promise 4 then放到微任务队列
 * 4. 循环微任务队列 2 5 6 
 * 5. 循环宏任务队列
 */

@xllpiupiu
Copy link

/**
 * 1. 分析以下程序段的输出顺序
 * 主要是考察微任务 宏任务
 */
setTimeout(()=>console.log(0))
new Promise((resolve)=>{
    console.log(1)
    resolve(2)
    console.log(3)
}).then(res=>console.log(res))
new Promise((resolve)=>{
    console.log(4)
    resolve(5)
}).then(res=>console.log(res)).then(()=>console.log(6))
console.log(8)
Promise.resolve(7).then(res=>console.log(res))
/**
 * 分析:1 3 4 2 5 6 0
 * 1. setTimeout放到宏任务队列
 * 2. 立即执行new Promise 1 3  then放到微任务队列
 * 3. 立即执行new Promise 4 then放到微任务队列
 * 4. 循环微任务队列 2 5 6 
 * 5. 循环宏任务队列
 */

1 3 4 8 2 5 7 6 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants