Promises如何处理立即解决?

Gre*_*Fox 0 javascript promise

尝试Promises,发现了一些我没想到的东西.

function Delayer(time){
	return new Promise((resolve,reject)=>{
		if(time != 0){
			setTimeout(()=>resolve("Waited " + (time/1000) + " secs!"),time)
		}
		else{
			resolve("No Time Waited");
		}
	})
}
var output = "Promise not resolved yet!";
console.log(output);
Delayer(10).then(function(msg){output = msg; console.log(output)});
console.log(output);//this wont change until callback.
Delayer(0).then(function(msg){output = msg; console.log(output)});
console.log(output);
Run Code Online (Sandbox Code Playgroud)

我希望这个Promise能像这样解决:

> Promise not resolved yet!
> Promise not resolved yet!
> No Time Waited
> No Time Waited
> Waited 3 secs!
Run Code Online (Sandbox Code Playgroud)

相反,我得到3"尚未解决",只有一个"没有时间等待".在处理立即解决之前,它显然正在等待代码的其余部分完成.它是如何做到的?

创建可能立即解决的承诺时,设计最佳实践是什么?

Nic*_*wer 6

promises规范要求它们始终异步调用回调,即使promise已经处于已解析状态.这是一个非常有益的质量,因为您可以确保您的代码始终以相同的顺序执行,无论是否必须等待.如果promises有时会同步调用回调,那么执行的顺序将取决于promise的内部状态,可能会导致错误.

特别是,参见Promise a + spec的要求2.2.4 :

onFulfilled或者onRejected在执行上下文堆栈仅包含平台代码之前不得调用.

  • Sentance在JavaScript的["The Hard Parts"](https://frontendmasters.com/live-event/javascript-hard-parts-live/)上有一个很好的课程,其中详细介绍了执行上下文堆栈的工作原理使用Frontend Masters上的异步代码 (2认同)
  • @GreenFox基本上,`.then`函数内的代码表示`if(isAlreadyResolved){setImmediate(()=> callback())}`而不是`if(isAlreadyResolved){callback()}` (2认同)