JavaScript学习笔记【setTimeout】
先看两个例子
console.log(1);
setTimeout(function () {
console.log(2);
}, 0);
console.log(3);
上面代码输出结果是1 3 2
无论setTimeout的执行时间是0还是1000,结果都是先输出3后输出2
for (var i = 0; i < 4; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
输出结果为 4 4 4 4
一、JavaScript单线程
首先我们要知道JavaScript 是单线程的。JS在同一时间内只能做一件事,这也常被称为 “阻塞式执行”。
可以采用异步来实现非堵塞执行。
任务队列:一个先进先出的队列,它里面存放着各种事件和任务。
所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。
- 输出
- 变量的声明
- 同步函数
异步任务:
- setTimeout和setInterval
- DOM事件
- Promise
- process.nextTick
- fs.readFile
- http.get
- 异步函数
除此之外,任务队列又分为macro-task(宏任务)与micro-task(微任务),在ES5标准中,它们被分别称为task与job。
二、setTimeout运行机制
setTimeout是异步的,运行机制是指定的代码,必须等到本次执行的所有同步代码都执行完,才会执行。
这里解释下异步执行过程:
浏览器有个定时器(timer)模块,定时器到了执行时间才会把异步任务放到异步队列,for循环体执行的过程中并没有把setTimeout放到异步队列中,只是交给定时器模块了。
4个循环体执行速度非常快(不到1毫秒)。定时器(即使设置了0默认也是4毫秒)到了设置的时间才会把setTimeout语句放到异步队列中。
图片来源叫我汤先森
三、解决方法
对于上面第二个例子想要得到0 1 2 3的结果可以使用以下方法。
方法一:使用let
使用let,不要用var,因为let是有作用域的,所以setTimeout的值指向的是每个循环体中的值
for (let i = 0; i < 4; i++) {
setTimeout(function () {
console.log(i);
}, 1000);
}
方法二:使用闭包
for (var i = 0; i < 4; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, 1000 * i)
})(i);
}
因为每个i的值都会传入function中,setTimeout中的i作用域在这个闭包中
基于Promise的解决方案(暂未理解)
const tasks = [];
const output = (i) => new Promise((resolve) => {
setTimeout(() => {
console.log(i);
resolve();
}, 1000 * i);
});
//生成全部的异步操作
for (var i = 0; i < 5; i++) {
tasks.push(output(i));
}
//同步操作完成后,输出最后的i
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(i);
}, 1000)
})
使用ES7中的async await特性的解决方案(暂未理解)
const sleep = (timeountMS) => new Promise((resolve) => {
setTimeout(resolve, timeountMS);
});
(async () => { //声明即执行的async
for (var i = 0; i < 5; i++) {
await sleep(1000);
console.log(i);
}
await sleep(1000);
console.log(i);
})();
www.cnblogs.com/tangjianqia… www.jianshu.com/p/3facc9bd8…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!