Promise-all方法實現
Promise 的 all 靜態方法特點
- all 方法會返回一個新的 Promise 對象
- 會按照傳入數組的順序將所有 Promise 中成功返回的結果保存到一個新的數組返回
- 數組中有一個 Promise 失敗就會失敗, 只有所有成功才會成功
博主這里就廢話不多說直接上代碼了:
static all(list) {
return new MyPromise(function (resolve, reject) {
let arr = [];
let count = 0;
for (let i = 0; i < list.length; i++) {
let p = list[i];
p.then(function (value) {
arr.push(value);
count++;
if (list.length === count) {
resolve(arr);
}
}).catch(function (e) {
reject(e);
});
}
});
}
完整的代碼如下:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>promise-all方法實現</title>
</head>
<body>
<script>
// 定義常量保存對象的狀態
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class MyPromise {
constructor(handle) {
// 0.初始化默認的狀態
this.status = PENDING;
// 定義變量保存傳入的參數
this.value = undefined;
this.reason = undefined;
// 定義變量保存監聽的函數
// this.onResolvedCallback = null;
// this.onRejectedCallback = null;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks = [];
// 1.判斷是否傳入了一個函數, 如果沒有傳入就拋出一個異常
if (!this._isFunction(handle)) {
throw new Error("請傳入一個函數");
}
// 2.給傳入的函數傳遞形參(傳遞兩個函數)
handle(this._resolve.bind(this), this._reject.bind(this));
}
then(onResolved, onRejected) {
return new MyPromise((nextResolve, nextReject) => {
// 1.判斷有沒有傳入成功的回調
if (this._isFunction(onResolved)) {
// 2.判斷當前的狀態是否是成功狀態
if (this.status === FULFILLED) {
try {
// 拿到上一個promise成功回調執行的結果
let result = onResolved(this.value);
// console.log("result", result);
// 判斷執行的結果是否是一個promise對象
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else {
// 將上一個promise成功回調執行的結果傳遞給下一個promise成功的回調
nextResolve(result);
}
} catch (e) {
nextReject(e);
}
}
}
// 1.判斷有沒有傳入失敗的回調
// if(this._isFunction(onRejected)){
try {
// 2.判斷當前的狀態是否是失敗狀態
if (this.status === REJECTED) {
let result = onRejected(this.reason);
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else if (result !== undefined) {
nextResolve(result);
} else {
nextReject();
}
}
} catch (e) {
nextReject(e);
}
// }
// 2.判斷當前的狀態是否是默認狀態
if (this.status === PENDING) {
if (this._isFunction(onResolved)) {
// this.onResolvedCallback = onResolved;
this.onResolvedCallbacks.push(() => {
try {
let result = onResolved(this.value);
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else {
nextResolve(result);
}
} catch (e) {
nextReject(e);
}
});
}
// if(this._isFunction(onRejected)){
// this.onRejectedCallback = onRejected;
this.onRejectedCallbacks.push(() => {
try {
let result = onRejected(this.reason);
if (result instanceof MyPromise) {
result.then(nextResolve, nextReject);
} else if (result !== undefined) {
nextResolve(result);
} else {
nextReject();
}
} catch (e) {
nextReject(e);
}
});
// }
}
});
}
catch(onRejected) {
return this.then(undefined, onRejected);
}
_resolve(value) {
// 這里是為了防止重復修改
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
// this.onResolvedCallback(this.value);
this.onResolvedCallbacks.forEach(fn => fn(this.value));
}
}
_reject(reason) {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
// this.onRejectedCallback(this.reason);
this.onRejectedCallbacks.forEach(fn => fn(this.reason));
}
}
_isFunction(fn) {
return typeof fn === "function";
}
static all(list) {
return new MyPromise(function (resolve, reject) {
let arr = [];
let count = 0;
for (let i = 0; i < list.length; i++) {
let p = list[i];
p.then(function (value) {
arr.push(value);
count++;
if (list.length === count) {
resolve(arr);
}
}).catch(function (e) {
reject(e);
});
}
});
}
}
</script>
<script>
let p1 = new MyPromise(function (resolve, reject) {
// resolve("111");
reject("aaa");
});
let p2 = new MyPromise(function (resolve, reject) {
setTimeout(function () {
resolve("222");
}, 5000);
});
let p3 = new MyPromise(function (resolve, reject) {
setTimeout(function () {
resolve("333");
}, 3000);
});
let pp = MyPromise.all([p1, p2, p3]);
console.log(pp);
pp.then(function (result) {
console.log("成功", result);
}, function (err) {
console.log("失敗", err);
});
</script>
</body>
</html>

浙公網安備 33010602011771號