分析:
网上找了的方法:都是用一个返回一个promise函数,并把状态的更改放在setTimeout函数里,
这里只是解释一下。
代码展示:
这个代码还没有实现sleep函数,只是讲一下流程(你们可以想一想输出结果)
async function main() {
var sleep = () => {
return new Promise((resolve, reject) => {
console.log("sleep函数里的代码")
resolve();
})
}
console.log("同步执行代码开始");
await sleep();
console.log("1");
console.log("2");
}
main();
console.log("main");
结果:
同步执行代码开始
sleep函数里的代码
main
1
2
可见,sleep函数实现了代码的暂停,但是只是暂停了async函数的代码运行,同步代码(输出main的这一行仍然会执行)
流程:
1. 代码首先执行main函数:进入main函数之后,首先执行 ”同步执行代码开始“ 接着进入sleep函数。
2. 代码进入sleep函数,执行 “sleep函数里面的代码” (注意:我们所说的promise是异步代码的解决方案,并不意味着Promise构造函数传入的代码是异步的,而是then函数(await表达式后面的)是异步的) 执行到 resolve() 之后,推入任务队列。此时await 后面的代码都被推到微任务队列。
3. 之后代码开始执行 "main" 然后同步代码执行完毕,开始执行异步代码,就是执行await后面的代码。
分析:
想要实行sleep函数,就要利用await返回的如果是promise对象,那么promise对象没有发生改变(没有执行resolve函数)就不会进行下一步的特性 。
实现:(自己尝试着写一下输出结果)
async function main() {
var sleep = (delaytime = 1000) => {
return new Promise((resolve, reject) => {
setTimeout(()=>{
console.log("睡眠结束");
resolve()
console.log("promise状态改变");
},delaytime)
console.log("sleep函数里的代码");
})
}
console.log("同步执行代码开始");
await sleep(6000);
console.log("1");
console.log("2");
}
main();
console.log("main");
结果:
首先输出
同步执行代码开始
sleep函数里的代码
main
隔(大约)6s之后执行
睡眠结束
promise状态改变
1
2
分析:
之前的同步执行代码跟上一个代码段一样,当执行到sleep函数之后Promise里函数执行,将setTimeout推入宏任务队列,接着,输出“sleep函数的代码”,然后输入同步代码里的 “main”。
同步代码执行完毕,执行任务队列里的代码:开始倒计时,计时结束之后输出 “睡眠结束” ,然后执行 resolve() (此时promise对象已经变化,将await后面的内容推入微任务队列),然后继续执行
“promise状态改变”。
接着,执行微任务队列里的代码,也就是await后面的内容。
至此,就实现了sleep函数。
PS:
为什么sleep函数要返回一个promise对象?
因为如果await表达式返回的不是promise对象,那么他会将返回结果包装成promise对象,状态直接改变,直接推入微任务队列。感兴趣的可以试着sleep函数不返回promise对象,看看输出结果是什么。
为什么要用setTimeout?
可以设置时间间隔,让过一段时间之后再去改变promise对象的状态,实现sleep功能。
同步代码,任务队列可以在其他博客上找一些说明,都很详细的。
如果文章有什么问题或者各位有什么不懂的都可以留言,一起讨论。