ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Promise结合setTimeout--promise练习题(2)

2021-09-26 16:31:06  阅读:161  来源: 互联网

标签:练习题 promise1 promise2 console log -- 队列 resolve promise


Promise结合setTimeout

题目1

console.log('start')
setTimeout(() => {
  console.log('time')
})
Promise.resolve().then(() => {
  console.log('resolve')
})
console.log('end')`

输出:

start
end
resolve
time

分析:

  1. 执行同步代码:
    • 打印start
    • 设置计时器(setTimeout),回调函数进入宏任务队列
    • 执行Promise.resolve.then(),回调函数是异步函数,进入微任务队列
    • 打印end
  2. 检查微任务队列,将其中任务放入执行栈执行——console.log('resolve');,队列空
  3. 检查宏任务队列,将其中任务放入执行栈执行—— console.log('time')

同-->微-->宏

题目2

const promise = new Promise((resolve, reject) => {
  console.log(1);
  setTimeout(() => {
    console.log("timerStart");
    resolve("success");
    console.log("timerEnd");
  }, 0);
  console.log(2);
});
promise.then((res) => {
  console.log(res);
});
console.log(4);

输出:

1
2
4
timeStart
timeEnd
success

分析:

  1. 执行同步代码:
    • 给promise赋值
    • 打印1
    • 设置计时器,回调函数是异步函数,进入宏任务队列
    • 打印2
    • 给promise的解决处理函数赋值(resolve指向一个函数),但因为promise尚未调用resolve,所以该回调函数尚未进入任务队列
    • 打印4
  2. 检查微任务队列,为空
  3. 检查宏任务队列,依次执行
console.log("timerStart");  
resolve("success");
console.log("timerEnd");

因为resolve是异步函数,会被放入微任务队列,当宏任务队列所有能执行的任务都取出后,开始新的循环
3. 执行栈为空,检查微任务队列,将微任务队列中的resolve放入执行栈执行,于是打印success

箭头函数能够保留它创建时的作用域,调用该作用域中的变量和函数,所以setTimeout改变执行流后,仍能调用resolve。

题目3

(1)

setTimeout(() => {
  console.log('timer1');
  setTimeout(() => {
    console.log('timer3')
  }, 0)
}, 0)
setTimeout(() => {
  console.log('timer2')
}, 0)
console.log('start')

输出:

start
timer1
timer2
timer3

(2)

setTimeout(() => {
  console.log('timer1');
  Promise.resolve().then(() => {
    console.log('promise')
  })
}, 0)
setTimeout(() => {
  console.log('timer2')
}, 0)
console.log('start')

输出:

start
timer1
promise
timer2

分析:

Promise.then是微任务,它会被加入到本轮中的微任务列表,而定时器timer3是宏任务,它会被加入到下一轮的宏任务中。

题目3

Promise.resolve().then(() => {
  console.log('promise1');
  const timer2 = setTimeout(() => {
    console.log('timer2')
  }, 0)
});
const timer1 = setTimeout(() => {
  console.log('timer1')
  Promise.resolve().then(() => {
    console.log('promise2')
  })
}, 0)
console.log('start');

输出:

start
promise1
timer1
promise2
timer2

分析:

  1. 执行同步代码:
    • Promise.resolve.then()给resolve赋予一个箭头函数。该回调加入本轮微任务队列中,其中的定时器timer2将加入次轮宏任务队列
    • 给timer1设置一个定时器,回调函数加入本轮宏任务队列,promise.then加入次轮微任务队列
    • 打印start
  2. 检查微任务队列:
    • 第一个Promise的解决处理函数被放入执行栈
    • 打印promise1
    • 为timer2添加定时器,回调函数加入本轮宏任务队列(已经是第二轮了)
    • 执行栈为空
  3. 检查宏任务队列
    • timer1定时器的回调函数转移到执行栈上
    • 打印timer1
    • 将第二个Promise的解决处理函数加入本轮微任务队列(已经是第二轮了)
    • 执行栈为空
  4. 检查微任务队列
    • 打印promise2
  5. 检查宏任务队列
    • 打印timer2

image

题目4

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    //console.log("success setTimeout");
    resolve('success')
  }, 1000)
})
const promise2 = promise1.then(() => {
  throw new Error('error!!!')
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
  console.log('promise1', promise1)
  console.log('promise2', promise2)
}, 2000)

输出:

promise1 Promise{<pending>}
promise2 Promise{<pending>}
//success setTimeout
Uncaught (in promise) Error: error!!!
promise1 Promise{<fulifilled> success}
promise2 Promise{<rejected> Error: error!!!}

分析:

  1. 执行同步代码
    • 给promise1赋值
    • 设置一个定时器,1秒后回调函数进入本轮宏任务队列
    • 给promise2赋值,then的回调函数加入微任务队列
    • 打印"promise1"和promise1的状态,目前promise1的状态依然是pending
    • 打印"promise2"和promise2的状态,目前promise2的状态依然是pending
    • 设置定时器,2秒后回调函数加入宏任务队列
  2. 检查微任务队列,空
  3. 检查宏任务队列,空
  4. 1秒,微任务队列依然为空
  5. 1秒,定时器触发,执行resolve("success");
  6. promise2的处理函数被放入微任务队列
  7. 将微任务队列的回调函数放入执行栈处理——throw new Error("error!!!"),抛出错误
  8. 2秒,微任务队列为空
  9. 2秒,将宏任务调入执行栈执行
  console.log('promise1', promise1)
  console.log('promise2', promise2)

此时promise1-->fulfilled,promise2-->rejected

可以提前给期约的处理函数赋值,但只有当状态转变时,回调函数才会进入微任务队列
如果先转状态,那么给相应处理函数赋值时,回调函数就会进入微任务队列

题目5

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("success");
    console.log("timer1");
  }, 1000);
  console.log("promise1里的内容");
});
const promise2 = promise1.then(() => {
  throw new Error("error!!!");
});
console.log("promise1", promise1);
console.log("promise2", promise2);
setTimeout(() => {
  console.log("timer2");
  console.log("promise1", promise1);
  console.log("promise2", promise2);
}, 2000);

输出:

promise1里的内容
promise1 Promise{<pending>}
promise2 Promise{<pending>}
timer1
Uncaught (in promise) Error: error!!!
timer2
promise1 Promise{<fulfilled> success}
promise2 Promise{<rejected> Error error!!!}

分析:
与上一题类似

感谢阅读。

百炼成钢!!!

参考:

【建议星星】要就来45道Promise面试题一次爽到底(1.1w字用心整理)
《JavaScript高级程序设计》(第四版)

标签:练习题,promise1,promise2,console,log,--,队列,resolve,promise
来源: https://www.cnblogs.com/liulangbxc/p/15338736.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有