new Promise(function(resolve, reject){ … } /* executor */)
Promise是一个构造函数,执行时立即调用executor函数,resolve和reject两个函数作为参数传递给executor。
resolve, reject函数被调用分别会将promise状态改为fulfilled(完成)或rejected(失败)
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
这个构造函数必须接受一个函数,否则会报错:
Promise.resolve(value)
类方法,返回一个以给定value决定的Promise对象。
1.如果该值是thenable(即带有then方法),返回的Promise对象的最终状态由then方法执行决定;
2.如果该value为空、基本类型或者不带then方法的对象,则返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法;
let p0 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve('success');
}, 250);
});
let p1 = Promise.resolve(p0);
console.log(p0 === p1); // true
p1.then(function(msg){
console.log('Yay! ' + msg); // Yay! success
})
传入 thenable 对象,返回 Promise 对象跟随 thenable 对象的最终状态。
Promise.reject(reason)
Promise.reject(reason)方法也会返回一个新的Promise实例,该实例的状态为rejected。参数reason会被传递给实例的回调函数。
let p0 = Promise.reject('error');
p0.then(null, function(err){
console.log(err);
});
// error
Promise.prototype.then
最多可接受两个参数,Promise的成功和失败情况的回调
let p0 = new Promise(function(resolve, reject){
//异步操作
setTimeout(function(){
// 生成1-10之间的随机数
var num = Math.ceil(Math.random() * 10);
if(num <= 5){
resolve(num);
}else {
reject('err');
}
}, 1000);
});
p.then(function(res){
console.log('resolved', res);
}, function(err){
console.log('rejected', err);
})
会随机的执行resolve,reject的方法;
then方法接受的参数是函数,但如果传递的并非是一个函数,那么then将创建一个没有经过回调函数处理的新的Promise对象,这个新Promise只是简单的接受调用这个then的原Promise的终态作为它的终态。
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
// 1
Promise.prototype.catch
该方法和then的第二个参数一样,用来指定reject的回调:
p.then(function(res){
console.log('resolved', res);
}).catch(function(err){
console.log('rejected', err);
});
但它们之前还有个区别,就是在执行then中第一个参数即resolve的回调时,如果代码执行报错或异常,那么就会进到这个catch方法中:
p.then(function(res){
console.log('resolved', res);
console.log(error); // 未定义
}).catch(function(err){
console.log('rejected', err);
});
Promise.all(itertable)
在 iterable 参数内所有的 promise 都“完成(resolved)”或参数中不包含 promise 时回调完成(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。
var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
// [3, 42, "foo"]
Promise.race(itertable)
返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value);
// 谁先执行完,就以谁为准执行回调
});
// "two"
下面实现一个简单的Promise:
大体结构如下:
function Promise(resolver){
if(typeof resolver !== 'function'){
throw new Error('Promise resolver undefined is not a function');
}
// 当前promise对象的状态
var status = 'pending',
// 当前promise对象的数据
value = undefined,
// 当前对象注册的回调方法队列
callbacks = [];
function resolve(newValue) {}
function reject(err) {}
resolver(resolve, reject);
this.then = function(onFulfilled, onRejected) {}
}
Promise.all = function(iterable) {}
Promise.race = function(iterable) {}
下面来实现resolve方法:
function resolve(newValue) {
if(newValue && (typeof newValue === 'object' || typeof newValue === 'function')){
var then = newValue.then;
if(typeof then === 'function'){
then.call(newValue, resolve, reject);
return;
}
}
status = 'fulfilled';
value = newValue;
executeCallbacks(); //执行回调
}
reject方法
function reject(err) {
status = 'rejected';
value = err;
executeCallbacks();
}
处理executeCallbacks方法:
function executeCallbacks() {
setTimeout(function(){
callbacks.forEach(function(cb){
handle(cb);
});
}, 0);
}
then方法:
this.then = function(onFulfilled, onRejected) {
// 链式调用,会返回一个新的Promise
return new Promise({
handle({
onFulfilled: onFulfilled || null,
onRejected: onRejected || null,
resolve,
reject
});
});
}
处理handle函数:
function handle(callback) {
if(status == 'pending'){
callbacks.push(cb);
return;
}
var cb = status == 'resolved' ? callback.onFulfilled : callback.onRejected;
if(cb === null){
cb = status == 'resolved' ? callback.resolve : callback.reject;
cb(value);
return;
}
var ret = cb(value);
try{
callback.resolve(ret);
}catch(err){
callback.reject(err);
}
}
最后咱们实现Promise.all
Promise.all = function(iterable) {
var self = this;
return new this(function(resolve, rejct){
if(!iterable || !Array.isArray(iterable)){
return reject(new TypeError('must be an array'));
}
var len = iterable.length;
if(!len){return resolve([])};
var results = [], called = false;
iterable.forEach(function(it, index){
(function(i){
self.resolve(it).then(function(res){
results[i] = res;
if(!called && results.length == len){
called = true;
return resolve(results);
}
}, function(err){
called = true;
return reject(err);
});
})(index);
});
});
}
实现Promise.race
Promise.race = function(iterable){
var self = this;
return new this(function(resolve, rejct){
if(!iterable || !Array.isArray(iterable)){
return reject(new TypeError('must be an array'));
}
var len = iterable.length;
if(!len){return resolve([])}
var called = false;
iterable.forEach(function(it){
self.then(functoin(res){
if(!called){
called = true;
return resolve(res);
}
}, function(err){
if(!called){
called = true;
return reject(err);
}
});
});
});
}