Promise定义
A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled.Promises/A+
Promise实现
状态机
Promise实际是一个状态机,从后面需要用到的状态开始实现Promise.
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
//存储三种状态:PENDING, FULFILLED, REJECTED.初始状态是PENDING
var state = PENDING;
//存储结果或者错误,一旦FULFILLED 或者 REJECTED
var value = null;
//存储sucess和failure处理函数,绑定在.then和.done
var handlers = [];
}
下一步,添加两种过渡状态fulfilling和rejecting:
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
// store state which can be PENDING, FULFILLED or REJECTED
var state = PENDING;
// store value once FULFILLED or REJECTED
var value = null;
// store sucess & failure handlers
var handlers = [];
function fulfill(result) {
state = FULFILLED;
value = result;
}
function reject(error) {
state = REJECTED;
value = error;
}
}
上面是两种初级过渡,下面是更高级的过渡,叫做resolve:
var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;
function Promise() {
// store state which can be PENDING, FULFILLED or REJECTED
var state = PENDING;
// store value once FULFILLED or REJECTED
var value = null;
// store sucess & failure handlers
var handlers = [];
function fulfill(result) {
state = FULFILLED;
value = result;
}
function reject(error) {
state = REJECTED;
value = error;
}
function resolve(result) {
try {
var then = getThen(result);
if (then) {
doResolve(then.bind(result), resolve, reject)
return
}
fulfill(result);
} catch (e) {
reject(e);
}
}
}
/**
* Check if a value is a Promise and, if it is,
* return the `then` method of that promise.
*
* @param {Promise|Any} value
* @return {Function|Null}
*/
function getThen(value) {
var t = typeof value;
if (value && (t === 'object' || t === 'function')) {
var then = value.then;
if (typeof then === 'function') {
return then;
}
}
return null;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*
* @param {Function} fn A resolver function that may not be trusted
* @param {Function} onFulfilled
* @param {Function} onRejected
*/
function doResolve(fn, onFulfilled, onRejected) {
var done = false;
try {
fn(function (value) {
if (done) return
done = true
onFulfilled(value)
}, function (reason) {
if (done) return
done = true
onRejected(reason)
})
} catch (ex) {
if (done) return
done = true
onRejected(ex)
}
}
以上代码的简单实现看参考:https://github.com/then/promise/blob/master/src/core.js
Promise状态
Promise对象有以下几种状态:
pending: 初始状态, 非 fulfilled 或 rejected.
fulfilled: 成功的操作.(如果promise.then(f),立刻调用f)
rejected: 失败的操作.(如果promise.then(undefined, r),立刻调用r)
如果一个promise对象处在fulfilled或rejected状态而不是pending状态,那么它也可以被称为settled状态。你可能也会听到一个术语resolved,它表示promise对象处于settled状态,或者promise对象被锁定在了调用链中。settled不是一种状态,而是一种语法上的便利。
Promise方法
Promise.resolve(value/promise/thenable)
Promise.resolve(value)方法返回一个以给定值resolve掉的Promise对象。但如果这个值是thenable的(就是说带有then方法),返回的promise会“追随”这个thenable的对象,接收它的最终状态(指resolved/rejected/pendding/settled);否则这个被返回的promise对象会以这个值被fulfilled。
//Example
var p = Promise.resolve([1,2,3]);
p.then(function(v) {
console.log(v[0]); // 1
});
//Polyfill
Promise.resolve = function (value) {
return new Promise(function (resolve) {
resolve(value);
});
};
Promise.reject(reason)
Promise.reject(reason)方法返回一个用reason拒绝的Promise.
//Example
Promise.reject(new Error("fail")).then(function(error) {
// 未被调用
}, function(error) {
console.log(error); // 堆栈跟踪
});
//Polyfill
Promise.reject = function (value) {
return new Promise(function (resolve, reject) {
reject(value);
});
};
Promise.race(iterable)
Promise.race(iterable)方法返回一个promise,这个promise在iterable中的任意一个promise被解决或拒绝后,立刻以相同的解决值被解决或以相同的拒绝原因被拒绝。
//Example
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, "一");
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, "二");
});
Promise.race([p1, p2]).then(function(value) {
console.log(value); // "二"
// 两个都解决,但p2更快
});
//Polyfill
Promise.race = function (values) {
// TODO: this polyfill only supports array-likes
// it should support all iterables
return new Promise(function (resolve, reject) {
values.forEach(function(value){
Promise.resolve(value).then(resolve, reject);
});
});
};
Promise.all(iterable)
Promise.all(iterable) 方法返回一个promise,该promise会在iterable参数内的所有promise都被解决后被解决。
//Example
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 1000, "one");
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 2000, "two");
});
var p3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 3000, "three");
});
var p4 = new Promise(function(resolve, reject) {
setTimeout(resolve, 4000, "four");
});
var p5 = new Promise(function(resolve, reject) {
reject("reject");
});
Promise.all([p1, p2, p3, p4, p5]).then(function(value) {
console.log(value);
}, function(reason) {
console.log(reason) //"reject"
});
//Polyfill
Promise.all = function (arr) {
// TODO: this polyfill only supports array-likes
// it should support all iterables
var args = Array.prototype.slice.call(arr);
return new Promise(function (resolve, reject) {
if (args.length === 0) return resolve([]);
var remaining = args.length;
function res(i, val) {
if (val && (typeof val === 'object' || typeof val === 'function')) {
var then = val.then;
if (typeof then === 'function') {
var p = new Promise(then.bind(val));
p.then(function (val) {
res(i, val);
}, reject);
return;
}
}
args[i] = val;
if (--remaining === 0) {
resolve(args);
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i]);
}
});
};
Promise.prototype.then(onFulfilled, onRejected)
Promise实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。
//Example
var p1 = new Promise(function(resolve, reject) {
resolve("Success!");
// or
// reject ("Error!");
});
p1.then(function(value) {
console.log(value); // Success!
}, function(reason) {
console.log(reason); // Error!
});
Promise.prototype.catch(onRejected)
等同于调用Promise.prototype.then(undefined, onRejected)
//Example
var p1 = new Promise(function(resolve, reject) {
resolve("Success");
});
p1.then(function(value) {
console.log(value); // "Success!"
throw "oh, no!";
}).catch(function(e) {
console.log(e); // "oh, no!"
});
//Polyfill
Promise.prototype['catch'] = function (onRejected) {
return this.then(null, onRejected);
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。