sleep
=====
js中是没有sleep函数,本文模拟sleep函数实现,比较常见常见的问题就是红路灯。sleep函数可以延迟程序的执行,程序执行过程中能够捕获到异常并抛出。
1.Promise实现
代码语言:javascript复制 function sleep(time) {
return new Promise(resolve => {
setTimeout(() =>{
console.log(time, 'time')
resolve()
}
, time)
})
}
两种方式进行调用:
方式一
then回调横式调用,sleep(1000)执行完后再执行sleep(2000),sleep(2000)执行完后再执行sleep(3000)
代码语言:javascript复制 sleep(1000).then(
() => {
sleep(2000).then(
() => {
sleep(3000)
}
)
}
)
但是这种实现方式属于回调地狱,类似于用setTimeout实现的这种。虽然setTimeout
也能实现sleep,但是不建议这么使用,一是不美,二是不易控制。
setTimeout(()=>{
//业务逻辑
setTimeout(()=>{
//业务逻辑
setTimeout(()=>{
//业务逻辑
},3000)
},2000)
},1000)
方式二
优化一下上面Promise实现的代码,如下: Promise.resolve()
将现有对象转为promise对象,相当于new Promise(resolve => resolve())
,在then回调中执行sleep()方法,then回调会返回一个promise对象。
const main = () => {
Promise.resolve().then(() =>
sleep(1000)
).then(() =>
sleep(2000)
).then(() =>
sleep(3000)
).catch((error)=>
console.log('error')
)
}
main();
2.generator构造器实现
代码语言:javascript复制
function sleep(time) {
return new Promise(resolve => {
setTimeout(() => {
console.log(time, 'time')
resolve()
}, time)
})
}
function* main(time) {
yield sleep(time)
}
main(1000).next().value.then(()=>{
console.log('1s后输出')
})
在调用main函数(Generator函数)时,它不会执行,也不会返回结果,而是指向内部状态的指针对象(遍历器对象Iterator Object),只有调用next()才会使指针指向下一个状态。下图是Generator函数的数据结构:
next()方法会执行generator的代码,其中 main(1000).next()
是对象,有两个值,一个是key为value的执行后的promise对象,一个是done判断generator是否执行完,如果done为true,说明程序已经执行完了。 要处理,则如下所示:
function sleep(time) {
return new Promise(resolve => {
setTimeout(() => {
console.log(time, 'time')
resolve()
}, time)
})
}
function* main(time) {
yield sleep(time)`在这里插入代码片`
}
const test = () => {
Promise.resolve().then(() =>
main(1000).next().value
).then(() =>
main(2000).next().value
).then(() =>
main(3000).next().value
)
}
test();
需要注意的是,如果直接这么写,则会在第1s后输出,第2s后输出,第3s后输出:
代码语言:javascript复制 function sleep(time) {
return new Promise(resolve => {
setTimeout(() => {
console.log(time, 'time')
resolve()
}, time)
})
}
function* main(time) {
yield sleep(time)
}
main(1000).next().value.then(()=>{
console.log('第1s后输出')
})
main(2000).next().value.then(()=>{
console.log('第12s后输出')
})
main(3000).next().value.then(()=>{
console.log('第s后输出')
})
3.async/await实现
用async/await使异步代码同步化,等await后面的函数执行完后再执行下面的代码。
代码语言:javascript复制function sleep(time) {
return new Promise(resolve => {
setTimeout(() => {
console.log(time, 'time')
resolve()
}, time)
})
}
async function main() {
await sleep(1000)
await sleep(2000)
await sleep(3000)
}
main()
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!