Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 延迟承诺。全部赢得';调用睡眠功能后,如果增加睡眠时间,则无法工作_Javascript_Typescript - Fatal编程技术网

Javascript 延迟承诺。全部赢得';调用睡眠功能后,如果增加睡眠时间,则无法工作

Javascript 延迟承诺。全部赢得';调用睡眠功能后,如果增加睡眠时间,则无法工作,javascript,typescript,Javascript,Typescript,在JS中编写代码时,我发现了有趣的行为 如以下代码所示,从sleep(0)开始不会产生任何延迟,而sleep(15)会产生延迟 //sleep.ts 导出默认函数睡眠(t:编号):承诺{ 返回新承诺((resolve)=>setTimeout(resolve,t)); } //loop.ts 异步函数doLoop(){ 设延迟=0; 常数增量=15; 等待承诺( 新数组(10).fill(0).map(异步()=>{ //这不行,不能耽搁。 等待睡眠(延迟); 延迟+=增量; //这很有效。

在JS中编写代码时,我发现了有趣的行为

如以下代码所示,从
sleep(0)
开始不会产生任何延迟,而
sleep(15)
会产生延迟

//sleep.ts
导出默认函数睡眠(t:编号):承诺{
返回新承诺((resolve)=>setTimeout(resolve,t));
}
//loop.ts
异步函数doLoop(){
设延迟=0;
常数增量=15;
等待承诺(
新数组(10).fill(0).map(异步()=>{
//这不行,不能耽搁。
等待睡眠(延迟);
延迟+=增量;
//这很有效。
延迟+=增量;
等待睡眠(延迟);
}
)
)
}
这两者有什么区别

在下面试试

//sleep.ts
功能睡眠(t){
返回新承诺((resolve)=>setTimeout(resolve,t));
}
//loop.ts
异步函数doLoop(){
设延迟=0;
常数增量=1000;
等待承诺(
新数组(3).fill(0).map(异步()=>{
//这不行,不能耽搁。
等待睡眠(延迟);
控制台日志(1,延迟);
延迟+=增量;
//这很有效。
延迟+=增量;
等待睡眠(延迟);
控制台日志(2,延迟);
}
)
)
}
doLoop()TLDR:

map()
回调函数使用当前值
delay
increment
,为数组中的每个项创建一个新的执行范围/上下文,然后将其推入回调队列,等待执行

在执行期间,每个回调的第一个
等待睡眠(延迟)
0毫秒的
延迟执行

让我们想想JavaScript中的事件循环和闭包

调用堆栈

调用堆栈是事件循环过程的一部分,它基本上保持 当前正在运行的函数的状态。这和我的想法很相似 堆栈数据结构的概念。(后进先出-后进先出)

现在,当调用
doLoop()
函数时,它被添加到调用堆栈中,并且在执行期间,它初始化变量
delay
increment
,并分别赋值
0
1000

接下来,它运行
await Promise.all()
,它也被添加到调用堆栈中以开始执行

接下来,
new Array(3).fill(0)
被添加到调用堆栈中并执行,然后返回
[0,0,0]
,该返回值被链接到
Array.map()
,该值也被添加到调用堆栈中以开始执行

Array.map()
对循环中的每个项执行的操作,并返回一个新数组

回调队列

这是事件循环过程的另一部分,异步代码被推送到事件循环过程中,并等待 执行。函数在这里排成一个队列,调用堆栈在这里查看,以获取完成后要执行的内容

链式
.map()
函数接受一个回调函数,该函数被相应地推送到回调队列中,因为它们是异步函数

闭包

这是函数记住创建它的范围/上下文的时候 即使函数在不同的范围内执行

将每个回调推入回调队列时,将根据当前值
delay
increment
创建一个新的执行范围/上下文

第一个
wait sleep(delay)
delay
0
执行,因为这是将其推入调用堆栈时的
delay


当第二个
等待睡眠(延迟)
在延迟增加后在调用堆栈中执行时,因此造成了实际的等待。

你怎么知道第一次睡眠没有延迟?我用
console.time
console.timeEnd
找到了答案。但是当它运行时,你的初始延迟只有0毫秒,这不解释为什么没有延迟吗?对不起,我没有正确阅读你的评论。我以为你说的是整个循环。可能第一个循环没有延迟,但是我指的是整个循环。谢谢你的详细解释!因此,根据我的理解,在第一种情况下,所有
sleep
函数都被推回到回调队列中,然后所有增量都发生在每个
sleep
函数完成之后。我理解正确了吗?*所有增量->每个增量是的,这是正确的。