likes
comments
collection
share

javaScript实现sleep函数(红绿灯实现思路)

作者站长头像
站长
· 阅读数 13

本文正在参加「金石计划」

sleep

js中是没有sleep函数,本文模拟sleep函数实现,比较常见常见的问题就是红路灯。sleep函数可以延迟程序的执行,程序执行过程中能够捕获到异常并抛出。

1.Promise实现

	function sleep(time) {
			return new Promise(resolve => {
				setTimeout(() =>{
					console.log(time, 'time')
					resolve()
				} 
				, time)
			})
		}

两种方式进行调用:

方式一

then回调横式调用,sleep(1000)执行完后再执行sleep(2000),sleep(2000)执行完后再执行sleep(3000)

		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构造器实现

	
	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函数的数据结构:

javaScript实现sleep函数(红绿灯实现思路)

next()方法会执行generator的代码,其中 main(1000).next()是对象,有两个值,一个是key为value的执行后的promise对象,一个是done判断generator是否执行完,如果done为true,说明程序已经执行完了。 javaScript实现sleep函数(红绿灯实现思路) 如果有多个时间需要处理,则如下所示:

	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后输出:

	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后面的函数执行完后再执行下面的代码。


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()
转载自:https://juejin.cn/post/7218576561842192443
评论
请登录