被js的setTimeout搞得头疼
在学习javascript的Promise对象,教程的其中一个源码是用123顺序执行几步算法。
<htmllang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="test-promise-log" style="border: solid 1px #ccc; padding: 1em; margin: 15px 0;">
<p>Log:</p>
</div>
</body>
'use strict';
varlogging=document.getElementById('test-promise-log');
while (logging.children.length>1) {
logging.removeChild(logging.children[logging.children.length-1]);
}
functionlog(s) {
varp=document.createElement('p');
p.innerHTML=s;
logging.appendChild(p);
}
// 0.5秒后返回input*input的计算结果:
functionmultiply(input) {
returnnewPromise(function (resolve, reject) {
log('calculating '+input+' x '+input+'...');
setTimeout(resolve, 500, input*input);
});
}
// 0.5秒后返回input+input的计算结果:
functionadd(input) {
returnnewPromise(function (resolve, reject) {
log('calculating '+input+' + '+input+'...');
setTimeout(resolve, 500, input+input);
});
}
varp=newPromise(function (resolve, reject) {
log('start new Promise...');
resolve(123);
});
p.then(multiply)
.then(add)
.then(multiply)
.then(add)
.then(function (result) {
log('Got value: '+result);
});
打算自己写js代码和原来用promise的代码比照来理解Promise的原理,但是原来程序的效果中步骤是每隔0.5打印的,结果我就卡在了实现隔秒的打印的settimeout函数上,我几次尝试的结果发现所有步骤都是同时被输出在页面上的:
不管是试图给每个函数后面设置延时:
'use strict'
varlogging=document.getElementById('test-promise-log');
while (logging.children.length>1) {
• logging.removeChild(logging.children[logging.children.length-1]);
}
functionlog(s) {
• varp=document.createElement('p');
• p.innerHTML=s;
• logging.appendChild(p);
}
// 0.5秒后返回input*input的计算结果:
functionmultiply(input) {
• log('calculating '+input+' x '+input+'...')
• returninput*input;
}
// 0.5秒后返回input+input的计算结果:
functionadd(input) {
• log('calculating '+input+' + '+input+'...')
• returninput+input;
}
log("Start Calculating...");
varresolve=123;
resolve=multiply(resolve);
setTimeout(function(){
• console.log('等待0.5秒');//结果是这4个console.log()0.5秒后同时在页面输出
},5000);
resolve=add(resolve);
setTimeout(function(){
• console.log('等待0.5秒');
},500);
resolve=multiply(resolve);
setTimeout(function(){
• console.log('等待0.5秒');
},500);
varresult=add(resolve);
setTimeout(function(){
• console.log('等待0.5秒');
},500);
log('Got value: '+result);
functionsleep(setTime)
{
varcurTime=Date.now();
while( Date.now() -curTime<setTime)
{
}
}
log("Start Calculating...");//步骤仍旧是同时被打印,而且网页加载花了很长时间
varresolve=123;
resolve=multiply(resolve);
sleep(500);
resolve=add(resolve);
sleep(500);
resolve=multiply(resolve);
sleep(500);
varresult=add(resolve);
sleep(500);
log('Got value: '+result);
还是试图在每个函数打印步骤的语句后面加上延时:
functionmultiply(input) {
setTimeout(function(){
• log('calculating '+input+' x '+input+'...');//步骤仍旧同时打印
},500);
returninput*input;
}
总之用了很多方法,都以失败告终;思考了一下自己是基于C语言顺序执行的逻辑来思考代码的,然而我对于setTimeout()的机制我一无所知
现求助目的如下:
2.推荐几个js异步编程和promise的练习题(注意是能动手代码练习的,不是教程解说)
回答
setTimeout 的机制是设定一个定时器任务,等有空的时候再来看看
无论设定多长时间,都要等有空了才会去看
也就是说就算定时器的时间已经到了,但是此时主线程没空,仍然不会去执行定时器任务
哪怕设定的时间是 0,也不会立即执行
并不是说定时器设定的多少时间就一定是那个时间一到就立刻执行
而是只有等到主线程有空的时候,再把那些到时间的定时器任务捞出来执行
要执行定时器任务有两个前提就是 有空 和 时间到了
你第一种写法,每个定时器都是设定的0.5秒,所以0.5秒过后,主线程一旦有空,就同时全部依次执行,因为每个定时器的时间都已经到了
而你第二种写法在你 sleep 的时候,主线程是没有空的,无论经过多少时间,都不会去执行定时器任务,只有等你全部 sleep 执行完毕后有空了再回过头来看前面的定时器任务,发现都超过设定时间了,所以也是同时全部依次执行
我这么说,说明白了吗
以上是 被js的setTimeout搞得头疼 的全部内容, 来源链接: utcz.com/a/107753.html