承诺完成执行后,javascript设置承诺回调

时间:2015-12-01 00:15:22

标签: 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/>');
	}
<button type="button" onclick='testPromise()' />test</button>
<div id="log"></div>

1 个答案:

答案 0 :(得分:4)

如果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);
}

您可以运行代码段以将输出视为:

Creating promise
Promise Created
Calling p.then()
After calling p.then()
In .then() handler

用语言来说,它会做到以下几点:

  1. 调用new Promise()构造函数
  2. Promise构造函数调用回调
  3. 记录“创造承诺”
  4. 回调解决了承诺
  5. 记录“Promise Created”
  6. 记录“调用p.then()”
  7. 就已解决的承诺调用p.then()。由于promise已经解决,因此只要当前的执行线程完成,就会安排.then()回调运行。
  8. 记录“调用p.then()”
  9. 之后
  10. 当前执行线程完成,然后promise调用.then()处理程序
  11. .then()处理程序记录“In .then()处理程序”