1.抽象表达:
Promise是JS中进行异步编程的新的解决方案。
2.具体表达:
从语法上来说: Promise是一个构造函数
从功能上来说: promise对象用来封装一个异步操作并可以获取其结果
3. promise的状态改变(只有2种, 只能改变一次)
pending变为resolved
pending变为rejected
4. promise的基本流程
一个 Promise 必然处于以下几种状态之一:
待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
已兑现(resolved): 意味着操作成功完成。
已拒绝(rejected): 意味着操作失败。
- 指定回调函数的方式更加灵活: 可以在请求发出甚至结束后指定回调函数
- 支持链式调用, 可以解决回调地狱问题
静态方法:
1.Promise.all(iterable) 这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。
2.Promise.race(iterable) 当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
3.Promise.reject(reason) 返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
4.Promise.resolve(value) 返回一个状态由给定value决定的Promise对象。value可能是一个普通值也可能是一个Promise
Promise 原型:
1.Promise.prototype.catch(onRejected) 添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入resolved状态,则以当前promise的完成结果作为新promise的完成结果.
2.Promise.prototype.then(onResolved, onRejected) 添加解决(resolve)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.
let myFirstPromise = new Promise(function(resolve, reject){
//当异步代码执行成功时,我们才会调用resolve(...), 当异步代码失败时就会调用reject(...)
//在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.
setTimeout(function(){
resolve("成功!"); //代码正常执行!
}, 250);
});
myFirstPromise.then(function(successMessage){
//successMessage的值是上面调用resolve(...)方法传入的值.
//successMessage参数不一定非要是字符串类型,这里只是举个例子
console.log("Yay! " + successMessage);
});
自定义Promise:
/*
自定义promise模块
*/
(function(window) {
const PENDING = "pending"; //初始值未确定状态
const RESOLVED = "resolved"; //成功状态
const REJECTED = "rejected"; //失败状态
// Promise构造函数
function Promise(excutor) {
const that = this;
that.status = PENDING; //指定状态属性,初始值为pending,代表初始值未确定状态
that.data = undefined; //用来存储结果数据的属性,初始值为undefined
that.callbacks = []; // {onResolved(){},onRejected(){}}
//将promise的状态改为,指定成功的value
function resolve(value) {
//如果当前状态不是pending。直接结束
if (that.status !== PENDING) return;
that.status = RESOLVED;
that.data = value;
//调用所有缓存的待执行成功的回调函数
if (that.callbacks.length > 0) {
//启动一个延迟时间为0的定时器,在定时器的回调函数中执行所有成功的回调函数
setTimeout(() => {
that.callbacks.forEach(obj => {
obj.onResolved(value);
})
})
};
};
//将promise的状态改为失败,指定失败的resaon
function reject(reason) {
//如果当前状态不是pending。直接结束
if (that.status !== PENDING) return;
that.status = REJECTED;
that.data = reason;
//调用所有缓存的待执行失败的回调函数
if (that.callbacks.length > 0) {
//启动一个延迟时间为0的定时器,在定时器的回调函数中执行所有失败的回调函数
setTimeout(() => {
that.callbacks.forEach(obj => {
obj.onRejected(reason);
})
})
}
};
//调用promise的状态改为失败,指定失败的reason
try {
excutor(resolve, reject);
} catch (error) { //执行器执行错误,当前promise变为失败
reject(error);
}
};
/* 用来指定成功/失败回调函数的方法
1.如果当前promise是pending,保存回调函数。
2.如果当前promise是resolved,异步执行成功的onResolved。
3.如果当前promise是rejected,异步执行成功的onRejected。
返回一个新的promise对象
它的结果状态由onResolved或onRejected执行的结果决定
1.抛出error => 变为rejected,结果值为error
2.返回值不是promise => 变为resolved,结果值为返回值
3.返回值是promise => 由这个promise的决定新的promise的结果(成功/失败)
*/
Promise.prototype.then = function(onResolved, onRejected) {
const that = this;
onResolved = typeof onResolved === 'function' ? onResolved : value => value; //将value向下传递
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; //将reason向下传递
return new Promise((resolve, reject) => {
//1.调用指定的回调函数callback
//2.根据callback()执行的结果更新then()返回的promise的状态
function handle(callback) {
try {
const result = callback(that.data);
if (!result instanceof Promise) {
resolve(result);
} else {
result.then( //取回调函数返回promise结果
value => resolve(value),
reason => reject(reason)
);
// result.then(resolve, reject);
}
} catch (error) {
reject(error);
}
}
if (that.status === RESOLVED) {
setTimeout(() => {
handle(onResolved);
});
} else if (that.status === REJECTED) {
setTimeout(() => {
handle(onRejected);
});
} else {
that.callbacks.push({ //不是直接保存成功/失败的回调,保存包含了回调函数的调用
onResolved(value) {
handle(onResolved);
},
onRejected(reason) {
handle(onRejected);
}
})
}
});
};
//用来指定失败回调函数的方法
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected);
};
//用来返回一个指定value的成功的Promise
//value可能是一个一般的值,也可能是promise对象;
Promise.resolve = function(value) {
return new Promise((resolve, reject) => {
//如果value是一个promise,最终返回的是promise的结果由value决定
if (value instanceof Promise) {
value.then(resolve, reject);
} else { //value不是promise,返回的是成功的promise,成功的值就是value
resolve(value);
}
})
};
//用来返回一个指定reason的失败的Promise
Promise.reject = function(reason) {
return new Promise((resolve, reject) => {
reject(reason);
})
};
//返回一个promise,只有当数组所有promise都成功才成功,否则失败
Promise.all = function(promises) {
return new Promise((resolve, reject) => {
let resolvedCount = 0; //已成功的数量
const values = new Array(promises.length); //用来保存成功promise的value值
promises.forEach((p, index) => {
p.then(value => {
resolvedCount++;
values[index] = value;
if (resolvedCount === promises.length) { //都成功了
resolve(values);
}
});
})
})
};
//返回一个promise,由第一个promise决定
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
promises.forEach(p => {
p.then(resolve, reject);
})
})
};
// 向外面暴露Promise
window.Promise = Promise;
})(window)