11-Promise常见手写
Promise.retry = (fn, options = {}) => { if (!isFunction(fn)) throw new Error('fn is not a function') const { max = 3, delay = 0 } = options let curMax = max const delayExec = () => delay && new Promise(resolve => setTimeout(resolve, delay)) return new Promise(async (resolve, reject) => { while (curMax > 0) { try { const res = await fn() resolve(res) return } catch (error) { await delayExec() curMax-- console.warn(`剩余次数${curMax}`) if (!curMax) reject(error) } } }) }function asyncPool(promiseFn, limit) { // 记录当前请求数 let currentRunFnNum = 0; // 记录当前pending队列 let pendingList = []; function run() { const [runTask,resolve, reject, ...params] = pendingList.shift(); runTask(...params).then(resolve).catch(reject).finnal(()=>{ currentRunFnNum -= 1; if(pendingList.length >0) { run(t) } }); } return (...params) => new Promise((resolve, reject) => { pendingList.push([ promiseFn, resolve, reject, ...params, ]); if(currentRunFnNum < limit) { currentRunFnNum +=1; run() } }); }interface asyncOpHistoryItem { fetchId: number; isResolve: boolean; result?: any; next?: (res: any) => void; } type PromiseFunction = (...props: any[]) => Promise<unknown>; function asyncOrderWrapper<T extends PromiseFunction>(fetch: T): T { const asyncOpHistory: asyncOpHistoryItem[] = []; const result = (...props: any[]) => { const fetchId = asyncOpHistory.length + 1; asyncOpHistory.push({ fetchId, isResolve: false, }); const resultUtil = (res: any, resolve: any) => { // 请求结束判断数组前是否有没有resolve的Promise for (let i = 0; i < fetchId - 1; i += 1) { if (asyncOpHistory[i].isResolve === false) { // 说明有那么带着返回结果等待执行 asyncOpHistory[fetchId - 1] = { fetchId, isResolve: true, result: res, next: resolve, }; return; } } // 没有 那么就直接resolve asyncOpHistory[fetchId - 1] = { fetchId, isResolve: true, }; resolve(res); // 如果当前id 小于数组长度 说明后面有请求请求完了等你呢。 let loopIndex = fetchId; let needLoop = true; while (loopIndex < asyncOpHistory.length && needLoop) { loopIndex += 1; const tempObj = asyncOpHistory[loopIndex - 1]; if (tempObj.isResolve && tempObj.next) { tempObj.next(tempObj.result); asyncOpHistory[loopIndex - 1] = { fetchId: loopIndex, isResolve: true, }; } else { needLoop = false; } } }; // console.log(asyncOpHistory) return new Promise((resolve, reject) => { fetch(...props).then((res: any) => { resultUtil(res, resolve); }).catch((res: any) => { resultUtil(res, reject); }); }); }; return result as T; }Promise.myAll = (PromiseFnList: (...params: any)=>Promise) => { let returnData = []; return new Promise((resolve, reject)=>{ PromiseList.map((i, index) => { Pomise.resolve(i).then((res)=>{ returnData[index] = res; // 每次请求结束后校验是否所有结果都返回了 let canResolve = true; for(i=0;i<PromiseList.length;i+=1) { if(!returnData[i]) { canResolve = false } } if(canResolve) resolve(returnData); }).catch(reject) }) }) }function asyncPool(promiseFnList, limit) { return new Promise((resolve, reject) =>{ let returnValue = []; let currentRunIndex = -1; function run() { currentRunIndex+=1 promiseFnList[currentRunIndex]().then(res=>{ returnValue[currentRunIndex] = res; if(returnValue.length === promiseFnList && !returnValue.find(n=>!!n)){ // 说明所有的请求运行完毕 结果都在请求中 resolve(returnValue) } if(currentRunIndex < promiseFnList.length) { // 此时说明有一个函数执行结束,但是仍有请求没执行完 run() } }).catch(reject) } promiseFnList.slice(0, limit).map(i=>{ run() }) }); }Promise.myRace = (PromiseFnList: (...params: any)=>Promise) => { return new Promise((resolve, reject)=>{ // done 用来销毁二次返回 let done = false; PromiseFnList.forEach(item => { //如果不是MyPromise对象,需要转换 Promise.resolve(item).then(res => { if (!done) { resolve(res); done = true; }; }, err => { if (!done) { reject(err); done = true; }; }); }) }) }let sleep = (time) => { return new Promise((res)=>{ setTimeout(()=>{ console.log('执行成功', tiem); res(); }, time) }) };
Last updated