承诺完成后javascript设置承诺回调

ale*_*440 0 javascript asynchronous promise

在下面的代码片段中,我试图在承诺完成设置Promise回调。

出于某种原因,它似乎“记住”在我期望未来完成它的执行之后执行回调。

为什么会这样?

	
	'use strict';
	var promiseCount = 0;
	
	function testPromise() {
		var thisPromiseCount = ++promiseCount;

		var log = document.getElementById('log');
		log.insertAdjacentHTML('beforeend', thisPromiseCount +
			') Started (<small>Sync code started</small>)<br/>');

		// We make a new promise: we promise the string 'result' (after waiting 3s)
		var p1 = new Promise(
			// The resolver function is called with the ability to resolve or
			// reject the promise
			function(resolve, reject) {
			
				log.insertAdjacentHTML('beforeend', thisPromiseCount +
					')  the promise is started(<small>Async code started</small>)<br/>');
				
				resolve(thisPromiseCount);

				log.insertAdjacentHTML('beforeend',promiseCount+ ') the promise is supposed to finish<br/>');
					
			});

			window.setTimeout(
				function() {
							log.insertAdjacentHTML('beforeend', thisPromiseCount +
								') we set the callback much after the proise has finished<br/>');
					p1.then(
						// Log the fulfillment value
						function(val) {
							log.insertAdjacentHTML('beforeend', val +
								') and still the promise executes the callback!(<small>Async code terminated</small>)<br/>');
						})
					.catch(
						// Log the rejection reason
						function(reason) {
							console.log('Handle rejected promise ('+reason+') here.');
						});
				}, 5000);

		log.insertAdjacentHTML('beforeend', thisPromiseCount +
			') Sync code terminated<br/>');
	}
Run Code Online (Sandbox Code Playgroud)
<button type="button" onclick='testPromise()' />test</button>
<div id="log"></div>
Run Code Online (Sandbox Code Playgroud)

jfr*_*d00 5

如果p是一个已经解决的承诺,然后你调用p.then(callback),它仍然会调用回调。这就是承诺的工作方式。这正如预期的那样。

但是,.then()回调将在执行此操作的执行线程执行p.then()完毕后异步调用(换句话说,不会立即调用,而是在稍微延迟后调用)。这是为了使.then()处理程序始终异步执行,无论它们被调用的承诺仍然挂起还是已经解决。这会创建一致的编程行为。

这是一个更简单的演示:

var p = new Promise(function(resolve, reject) {
    log("Creating promise");
    resolve();
});

log("Promise Created");

log("Calling p.then()");

p.then(function() {
    log("In .then() handler");
})
    
log("After calling p.then()");    


function log(msg) {
    var div = document.createElement("div");
    div.innerHTML = msg;
    document.body.appendChild(div);
}
Run Code Online (Sandbox Code Playgroud)

您可以运行该代码段以查看输出:

Creating promise
Promise Created
Calling p.then()
After calling p.then()
In .then() handler
Run Code Online (Sandbox Code Playgroud)

简而言之,它执行以下操作:

  1. 调用new Promise()构造函数
  2. Promise 构造函数调用回调
  3. 记录“创建承诺”
  4. 回调解决了承诺
  5. 记录“承诺已创建”
  6. 记录“调用 p.then()”
  7. 调用p.then()已解决的承诺。由于承诺已经解决,这会安排.then()回调在当前执行线程完成后立即运行。
  8. 记录“在调用 p.then() 之后”
  9. 当前执行线程完成,然后承诺调用.then()处理程序
  10. .then()处理程序日志“然后在()处理”