1.promise简介
1.1
Promise本意是承诺,在程序中的意思就是承诺我过一段时间后会给你一个结果。 什么时候会用到过一段时间?答案是异步操作,异步是指可能比较长时间才有结果的才做。
Promise表示一个异步操作的最终结果。与Promise最主要的交互方法是通过将函数传入它的then方法从而获取得Promise最终的值或Promise最终最拒绝(reject)的原因。
1.2 Promise状态
一个Promise必须处在其中之一的状态:pending, fulfilled 或 rejected.
如果是pending状态,则promise:
可以转换到fulfilled或rejected状态。
如果是fulfilled状态,则promise:
不能转换成任何其它状态。
必须有一个值,且这个值不能被改变。
如果是rejected状态,则promise可以:
不能转换成任何其它状态。
必须有一个原因,且这个值不能被改变。
”值不能被改变”指的是其identity不能被改变,而不是指其成员内容不能被改变。
1.3 then 方法
一个Promise必须提供一个then方法来获取其值或原因。
Promise的then方法接受两个参数:
promise.then(onFulfilled, onRejected)
onFulfilled 和 onRejected 都是可选参数:如果onFulfilled不是一个函数,则忽略之。如果onRejected不是一个函数,则忽略之。
如果onFulfilled是一个函数:它必须在promise fulfilled后调用, 且promise的value为其第一个参数。
它不能在promise fulfilled前调用。不能被多次调用。
如果onRejected是一个函数,它必须在promise rejected后调用, 且promise的reason为其第一个参数。
它不能在promise rejected前调用。不能被多次调用。
onFulfilled 和 onRejected 只允许在 execution context 栈仅包含平台代码时运行.
onFulfilled 和 onRejected 必须被当做函数调用 (i.e. 即函数体内的 this 为undefined).
对于一个promise,它的then方法可以调用多次.
当promise fulfilled后,所有onFulfilled都必须按照其注册顺序执行。
当promise rejected后,所有OnRejected都必须按照其注册顺序执行。
then 必须返回一个promise
promise2 = promise1.then(onFulfilled, onRejected);
如果onFulfilled 或 onRejected 返回了值x, 则执行Promise 解析流程[[Resolve]](promise2, x).
如果onFulfilled 或 onRejected抛出了异常e, 则promise2应当以e为reason被拒绝。
如果 onFulfilled 不是一个函数且promise1已经fulfilled,则promise2必须以promise1的值fulfilled.
如果 OnReject 不是一个函数且promise1已经rejected, 则promise2必须以相同的reason被拒绝.
2.使用promise
let promise = new Promise((resolve, reject) => {
setTimeout(function(){
let num =Math.random();
if(num<.5){
resolve(num);
}else{
reject('失败');
}
})
});
promise.then(Fulfilled,Rejected)
构造一个Promise实例需要给Promise构造函数传入一个函数。
传入的函数需要有两个形参,两个形参都是function类型的参数。
第一个形参运行后会让Promise实例处于resolve状态,所以我们一般给第一个形参命名为resolve,使 Promise 对象的状态改变成成功,同时传递一个参数用于后续成功后的操作
第一个形参运行后会让Promise实例处于reject状态,所以我们一般给第一个形参命名为reject,将 Promise 对象的状态改变为失败,同时将错误的信息传递到后续错误处理的操作
3 .自己实现promise
const PENDING = 'pending';//初始态
const FULFILLED = 'fulfilled';//成功态
const REJECTED = 'rejected';//失败态
function Promise(executor){
let self = this;//先缓存当前promise实例
self.status = PENDING;//设置状态
//定义存放成功的回调的数组
self.onResolvedCallbacks = [];
//定义存放失败回调的数组
self.onRejectedCallbacks = [];
//当调用此方法的时候,如果promise状态为pending,的话可以转成成功态,如果已经是成功态或者失败态了,则什么都不做
function resolve(value){
if(value!=null &&value.then&&typeof value.then == 'function'){
return value.then(resolve,reject);
}
//如果是初始态,则转成成功态
setTimeout(function(){
if(self.status == PENDING){
self.status = FULFILLED;
self.value = value;//成功后会得到一个值,这个值不能改
//调用所有成功的回调
self.onResolvedCallbacks.forEach(cb=>cb(self.value));
}
})
}
function reject(reason){
setTimeout(function(){
//如果是初始态,则转成失败态
if(self.status == PENDING){
self.status = REJECTED;
self.value = reason;//失败的原因给了value
self.onRejectedCallbacks.forEach(cb=>cb(self.value));
}
});
}
try{
//因为此函数执行可能会异常,所以需要捕获,如果出错了,需要用错误 对象reject
executor(resolve,reject);
}catch(e){
//如果这函数执行失败了,则用失败的原因reject这个promise
reject(e);
};
}
function resolvePromise(promise2,x,resolve,reject){
if(promise2 === x){
return reject(new TypeError('循环引用'));
}
let called = false;//promise2是否已经resolve 或reject了
if(x instanceof Promise){
if(x.status == PENDING){
x.then(function(y){
resolvePromise(promise2,y,resolve,reject);
},reject);
}else{
x.then(resolve,reject);
}
//x是一个thenable对象或函数,只要有then方法的对象,
}else if(x!= null &&((typeof x=='object')||(typeof x == 'function'))){
//当我们的promise和别的promise进行交互,编写这段代码的时候尽量的考虑兼容性,允许别人瞎写
try{
let then = x.then;
if(typeof then == 'function'){
//有些promise会同时执行成功和失败的回调
then.call(x,function(y){
//如果promise2已经成功或失败了,则不会再处理了
if(called)return;
called = true;
resolvePromise(promise2,y,resolve,reject)
},function(err){
if(called)return;
called = true;
reject(err);
});
}else{
//到此的话x不是一个thenable对象,那直接把它当成值resolve promise2就可以了
resolve(x);
}
}catch(e){
if(called)return;
called = true;
reject(e);
}
}else{
//如果X是一个普通 的值,则用x的值去resolve promise2
resolve(x);
}
}
//onFulfilled 是用来接收promise成功的值或者失败的原因
Promise.prototype.then = function(onFulfilled,onRejected){
//如果成功和失败的回调没有传,则表示这个then没有任何逻辑,只会把值往后抛
onFulfilled = typeof onFulfilled == 'function'?onFulfilled:function(value){return value};
onRejected = typeof onRejected == 'function'?onRejected:reason=>{throw reason};
//如果当前promise状态已经是成功态了,onFulfilled直接取值
let self = this;
let promise2;
if(self.status == FULFILLED){
return promise2 = new Promise(function(resolve,reject){
setTimeout(function(){
try{
let x =onFulfilled(self.value);
//如果获取到了返回值x,会走解析promise的过程
resolvePromise(promise2,x,resolve,reject);
}catch(e){
//如果执行成功的回调过程中出错了,用错误原因把promise2 reject
reject(e);
}
})
});
}
if(self.status == REJECTED){
return promise2 = new Promise(function(resolve,reject){
setTimeout(function(){
try{
let x =onRejected(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
})
});
}
if(self.status == PENDING){
return promise2 = new Promise(function(resolve,reject){
self.onResolvedCallbacks.push(function(){
try{
let x =onFulfilled(self.value);
//如果获取到了返回值x,会走解析promise的过程
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
});
self.onRejectedCallbacks.push(function(){
try{
let x =onRejected(self.value);
resolvePromise(promise2,x,resolve,reject);
}catch(e){
reject(e);
}
});
});
}
}
module.exports =Promise;
4 自己实现promise.all
function gen(times,cb){
let result = [],count=0;
return function(i,data){
result[i] = data;
if(++count==times){
cb(result);
}
}
}
Promise.all = function(promises){
return new Promise(function(resolve,reject){
let done =gen(promises.length,resolve);
for( let i=0;i<promises.length;i++){
promises[i].then(function(data){done(i,data);},reject);
}
});
}
5. 自己实现 Promise.race
Promise.race =function(promises){
return new Promise(function(resolve,reject){
for(let i=0;i<promises.length;i++){
promises[i].then(resolve,reject);
}
});
}
6. 自己实现 Promise.resolve
Promise.resolve =function(value){
return new Promise(function(resolve){
resolve(value);
});
}
7. 自己实现 Promise.resolve
Promise.reject =function(reason){
return new Promise(function(resolve,reject){
reject(reason);
});
}