源码参考https://github.com/kriskowal/…主要内容:promise的迭代设计中主要的代码片段,翻译一部分加上自己的理解,同时指出promise的一些特性。promise的雏形var maybeOneOneSecondLater = function () { var callback; setTimeout(function () { callback(1); }, 1000); return { then: function (_callback) { callback = _callback; } };};maybeOneOneSecondLater().then(callback1);promise诞生,比起传统回调,它返回了一个表示最终结果的对象(一个承诺),我们可以在这个对象上调用函数观察它的实现或者是拒绝。但本质上还是传入回调,任人宰割。好的是,promise在异步操作和回调之间提供了一个中间层,在这个中间层里可以搞一些事情,解决传统回调的蛋疼问题。改进后的promise可以让我们的回调不’任人宰割‘了。第一次改进很明显目前这个promise只能处理一个回调,传入多个回调会覆盖,所以数据结构上应该用一个数组来储存回调函数,需要执行的时候,依次执行。let defer = () => { let pending = [],value; return { resolve(_value){ value = _value for(let i = 0;i < pending.length; i++){ pendingi } pending = undefined; }, then(_callback){ if(pending){ pending.push(_callback) }else{ _callback(); } } }}let oneOneSecondLater = () => { let result = defer(); setTimeout(()=> { result.resolve(1); }, 1000); return result;};oneOneSecondLater().then(callback);这里对代码做一些解释:defer函数的作用:产生promise对象,可以理解为promise的构造函数;oneOneSecondLater函数封装了我们的异步操作setTimeout;result.resolve():异步操作完成后告诉promise,promise会替你执行回调,这是它作为一个中介应该做的;oneOneSecondLater().then(callback):oneOneSecondLater函数的使用者需要告诉promise,成功后执行什么;好了,目前我们的promise可以接受多次回调,并在异步操作完成后顺序执行了。第二次改进promise这个中介规定,异步操作只能成功一次(resove只能调用一次哟)。也就是说,使用promise封装异步操作的同事们不可能让你的回调执行两次了。。你就大胆的传进去吧。。let defer = () => { let pending = [],value return { resolve(_value){ if(pending){ value = _value for(let i = 0;i < pending.length; i++){ pendingi } pending = undefined; }else{ throw new Error(“A promise can only be resolved once.”) } }, then(_callback){ if(pending){ pending.push(_callback) }else{ _callback(); } } }}补充一点:因为promise在异步操作成功后,就将pending设为了undefined,这也说明,promise向我们保证了:异步状态一旦改变,就定格了。所以如果一个异步操作已经成功,你再传回调进去,那就会直接执行:if(pending){pending.push(_callback)}else{_callback();}第三次改进:职责分离let defer = () => { let pending = [],value; return { resolve(_value){ if(pending){ value = _value for(let i = 0;i < pending.length; i++){ pendingi } pending = undefined; }else{ throw new Error(“A promise can only be resolved once.”) } }, promise: { then (callback) { if (pending) { pending.push(callback); } else { callback(value); } } } }}这个改进就很小了,只是把then封装到promise对象中,让resolve和promise两个对象各司其职;resolve是在封装异步操作的时候用的,promise是在使用异步操作时候用的;第四次改进:加链式操作熟悉promise的同学应该知道,每次then执行完成后都是会默认返回promis的,就是为了方便链式操作。var defer = function () { var pending = [], value; return {// then called instead } resolve: function (_value) { if (pending) { value = ref(_value); // values wrapped in a promise for (var i = 0, ii = pending.length; i < ii; i++) { var callback = pending[i]; value.then(callback); pending = undefined; } }, promise: { then: function (_callback) { var result = defer(); // callback is wrapped so that its return // value is captured and used to resolve the promise // that “then” returns var callback = function (value) { result.resolve(_callback(value)); }; if (pending) { pending.push(callback); } else { value.then(callback); } return result.promise; } } };};有两个难点,怎么返回promise?resolve要考虑处理promise的情况?把callback包装到一个新promise中,callback执行的时候直接触发resolve这里有点难解释,日后再补。错误处理var defer = function () { var pending = [], value; return { resolve: function (_value) { if (pending) { value = ref(_value); for (var i = 0, ii = pending.length; i < ii; i++) { // apply the pending arguments to “then” value.then.apply(value, pending[i]); } pending = undefined; } }, promise: { then: function (_callback, _errback) { var result = defer(); var callback = function (value) { result.resolve(_callback(value)); }; var errback = function (reason) { result.resolve(_errback(reason)); }; if (pending) { pending.push([callback, errback]); } else { value.then(callback, errback); } return result.promise; } } };};let ref = (value) => { if (value && typeof value.then === “function”) return value; return { then: function (callback) { return ref(callback(value)); } };};let reject = (reason) => { return { then: function (callback, errback) { return ref(errback(reason)); } };};提供默认函数,一个容错 // 提供一个默认的成功回调和错误回调_callback = _callback || function (value) { // 默认执行 return value;};_errback = _errback || function (reason) { // 默认拒绝 return reject(reason);};安全性和稳定性保证callbacks和errbacks在未来他们被调用的时候,应该是和注册时的顺序是保持一致的。这将显著降低异步编程中流程控制出错可能性。let enqueue = (callback) => { setTimeout(callback,1)} resolve: function (_value) { if (pending) { value = ref(_value); for (let i = 0, ii = pending.length; i < ii; i++) { enqueue(function () { value.then.apply(value, pending[i]); }); } pending = undefined; }} let ref = function (value) { if (value && value.then) return value; return { then: function (callback) { let result = defer(); // XXX enqueue(function () { result.resolve(callback(value)); }); return result.promise; } };};let reject = function (reason) { return { then: function (callback, errback) { var result = defer(); // XXX enqueue(function () { result.resolve(errback(reason)); }); return result.promise; } };};执行的时候如果是异步任务,很有可能会乱?when函数和消息传递?