被js的setTimeout搞得头疼

在学习javascript的Promise对象,教程的其中一个源码是用123顺序执行几步算法。

被js的setTimeout搞得头疼

<!DOCTYPE html>

<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()的机制我一无所知

现求助目的如下:

1.实现无promise各个计算步骤的延时打印

2.推荐几个js异步编程和promise的练习题(注意是能动手代码练习的,不是教程解说)

回答

setTimeout 的机制是设定一个定时器任务,等有空的时候再来看看

无论设定多长时间,都要等有空了才会去看

也就是说就算定时器的时间已经到了,但是此时主线程没空,仍然不会去执行定时器任务

哪怕设定的时间是 0,也不会立即执行

并不是说定时器设定的多少时间就一定是那个时间一到就立刻执行

而是只有等到主线程有空的时候,再把那些到时间的定时器任务捞出来执行

要执行定时器任务有两个前提就是 有空 和 时间到了

你第一种写法,每个定时器都是设定的0.5秒,所以0.5秒过后,主线程一旦有空,就同时全部依次执行,因为每个定时器的时间都已经到了

而你第二种写法在你 sleep 的时候,主线程是没有空的,无论经过多少时间,都不会去执行定时器任务,只有等你全部 sleep 执行完毕后有空了再回过头来看前面的定时器任务,发现都超过设定时间了,所以也是同时全部依次执行

我这么说,说明白了吗

以上是 被js的setTimeout搞得头疼 的全部内容, 来源链接: utcz.com/a/107753.html

回到顶部