共计 4689 个字符,预计需要花费 12 分钟才能阅读完成。
Promise
的用法:
let p = new Promise(function(resolve, reject){console.log(111)
setTimeout(function(){resolve(2)
}, 1000)
})
p.then(function(res){console.log('suc',res)
},function(err){console.log('err',err)
})
能够看到 new 了一个 Promise, 外面有一个回调函数,回调函数里有 2 个参数,别离又是另外 2 个函数。其实外面很多也都是回调函数的封装调用。
const [PENDING,RESOLVED,REJECTED]=["PENDING","RESOLVED","REJECTED"];`
class Promise1 {constructor(executor){
state = PENDING;
value = undefined;
reason = undefined;
resolve = (value) => {if(this.state === PENDING){
this.state = RESOLVED;
this.value = value;
}
}
reject = (reason) => {if(this.state === PENDING){
this.state = REJECTED;
this.value = reason;
}
}
try{executor(this.resolve,this.reject)
}catch(e){reject(e)
}
}
}
测试一下执行状况:
let p1 = new Promise1((resolve,reject)=>{//function:executor
console.log(111)
setTimeout(()=>{resolve(111)//this.resolve, 间接传参调用
}, 1000)
})
上面就是 then
了
class Promise1 {constructor(executor){
...
onResolvedCallbacks=[]; //then,pending 里先存起来
onRejectedCallbacks=[];
...
resolve = (value) => {if(this.state === PENDING){
...
//executor 里如果是异步会把 then 里存起来, 而后 executor 走完了 resolved 的话, 会再调 then 里回调函数
this.onResolvedCallbacks.forEach(fn => fn(value))
}
}
reject = (reason) => {if(this.state === PENDING){
...
this.onRejectedCallbacks.forEach(fn => fn(reason))
}
}
}
then(onResolved,onRejected){
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason};
switch(this.state){
case RESOLVED : // 状态变了, 就间接把后果给进来
onResolved(this.value);
case REJECTED :
onRejected(this.reason);
case PENDING :
// 如果是 pending 的话, 阐明 executor 还没走完, 先存起来, 走完再调用
this.onResolvedCallbacks.push(onResolved);
this.onRejectedCallbacks.push(onRejected)
}
}
}
测试一下:
let p2 = new Promise1((resolve, reject) => {setTimeout(()=>{resolve(222)
}, 1000)
})
p2.then(res => console.log(res, 'res')) //222
链式调用:
class Promise1 {
...
then(onResolved,onRejected){
...
// 返回一个 promise1
let newPromise=new Promise1((resolve,reject)=>{switch(this.state){
case RESOLVED : // 状态变了, 就间接把后果给进来
setTimeout(()=>{//then, 放前面解决
try{let reValue=onResolved(this.value);
rePromise(newPromise,reValue,resolve,reject)
}catch(e){reject(e)}
},0)
case REJECTED :
setTimeout(()=>{
try{let reValue=onRejected(this.reason);
rePromise(newPromise,reValue,resolve,reject)
}catch(e){reject(e)}
},0)
case PENDING :
// 如果是 pending 的话, 阐明 executor 还没走完, 先存起来, 走完再调用
this.onResolvedCallbacks.push(()=>{setTimeout(()=>{
try{let reValue=onResolved(this.value);
rePromise(newPromise,reValue,resolve,reject)
}catch(e){reject(e)}
},0)
});
this.onRejectedCallbacks.push(()=>{setTimeout(()=>{
try{let reValue=onRejected(this.reason);
rePromise(newPromise,reValue,resolve,reject)
}catch(e){reject(e)}
},0)
})
}
})
return newPromise;
}
}
//newPromise: 新的 promise1 对象,reValue: 上一个 then 的返回值,newPromise.resolve,newPromise.reject
function rePromise(newPromise,reValue,resolve,reject){// 相当于把本人 return 进来了,let p2 = p.then(res => p2);
if(newPromise === reValue){reject(new TypeError('循环了'))
}
if(reValue !== null && (typeof reValue === 'object' || typeof reValue === 'function')){
try{
// 判断一下 reValue 是不是 promise1, 是个对象, 还带有 then 函数
// 如果有 then 并是个函数, 就调 then;
let then = reValue.then;
if(typeof then === 'function'){
then.call(reValue, res=>{resolve(res)
},err=>{reject(err)
})
}else{//then 不是函数, 间接用 resolve 返回值
resolve(reValue)
}
}catch(e){reject(e)
}
}else{// 只是个一般值
resolve(reValue)
}
}
测试一下:
p3.then(res => {console.log(res)
return new Promise1((resolve, reject) => {resolve('p3')
})
}).then(res => console.log(res, 'pp3'))//p3
但还有个问题
...
function rePromise(newPromise,reValue,resolve,reject){
...
let called;// 是否调用过, 避免屡次调用
if(reValue !== null && (typeof reValue === 'object' || typeof reValue === 'function')){
try{
let then = reValue.then;
if(typeof then === 'function'){
then.call(reValue, res=>{if(called) return;
called = true;
//promise1 就持续下一个, 直到 then 走完, 变成一般的值
rePromise(newPromise,res,resolve,reject)
},err=>{if(called) return;
called = true;
reject(err)
})
}else{//then 不是函数, 间接用 resolve 返回值
resolve(reValue)
}
}catch(e){if(called) return;
called = true;
reject(e)
}
}else{// 只是个一般值
resolve(reValue)
}
}
测试一下
let p1=new Promise1((resolve,reject)=>{resolve(111)
})
let p2=p1.then(res=>{console.log(res,'p1')},err=>console.log(err,'p1'));
p2.then(res=>console.log(res,'p2'))
.then(res=>console.log(res,'p3))
还有其它属性:
class Promise1 {
...
catch(onReject){return this.then(null,onReject)
}
defer(){let defer={};
defer.promise=new Promise1((resolve,reject)=>{
defer.resolve=resolve;
defer.reject=reject;
})
return defer;
}
deffered(){return this.defer;}
all(promises){return new Promise1((resolve,reject)=>{let done=gen(promises.length,resolve);
for(let i=0;i<promises.length,i++){promises[i].then(res=>{done(i,res)
},reject)
}
})
}
race(promises){return new Promise1((resolve,reject)=>{for(let i=0;i<promises.length;i++){promises[i].then(resolve,reject)
}
})
}
resolve(value){return new Promise1((resolve,reject)=>{resolve(value)
})
}
reject(reason){return new Promise1((resolve,reject)=>{reject(reason)
})
}
}
function gen(times,cb){const result=[];
let count=0;
return (i,data)=>{result[i]=data;
count+=1;
if(count===times){cb(result)
}
}
}
正文完
发表至: javascript
2021-02-08