[英]How to implement the equivalent of Promise.all for my Task implementation?
[英]What is the problem with my implementation of Promise.all()?
我正在嘗試編寫我的Promise.all()
函數。 它應該重復本機Promise.all()
方法的功能。
如果數組中只有 Promise,則代碼可以正常工作,如果數組包含 Promise 以外的內容,則可能會出現問題。
下面是一個執行示例:
const p1 = Promise.resolve(3);
const p2 = 1337;
const p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 10000, 'foo');
});
promiseAll([p1, p3, p3]).then(values => console.log(values)); // [3, 1337, "foo"]
這是我的代碼:
const promiseAll = promises => new Promise((resolve, reject) => {
if (promises.length === 0) { resolve([]); }
const results = [];
let resolved = 0;
promises.forEach(promise => {
if (!(promise instanceof Promise)) {
Promise.resolve(promise).then(data => results.push(data));
}
promise.then(result => {
results.push(result);
resolved += 1;
if (resolved === promises.length) {
resolve(results);
}
}, error => reject(error));
});
});
問題是什么?
您的實施存在兩個主要問題:
在forEach()
方法中,您有一個檢查: promise instanceof Promise
。 如果這個檢查是假的,你打電話Promise.resolve()
但是你也打電話 promise.then promise.then(...)
; 您可能打算在else
塊中調用then()
方法
Promise.all()
維持秩序 - 你的實現沒有。 這是因為您只需按照解決承諾的順序將承諾結果推送到results
數組中
您可以如下所示更改您的實現以解決上述問題:
const promiseAll = promises => {
return new Promise((resolve, reject) => {
if (promises.length === 0) {
resolve([]);
return;
}
const results = [];
let resolved = 0;
function collectResult(result, index) {
results[index] = result;
resolved += 1;
if (resolved === promises.length) {
resolve(results);
}
}
promises.forEach((value, index) => {
if (
typeof value === 'object' &&
'then' in value &&
typeof value.then === 'function'
) {
value.then(res => collectResult(res, index)).catch(reject);
} else {
Promise.resolve(value).then(res => collectResult(res, index));
}
});
});
};
您正在使用 Promise.resolve(promise) 創建一個新的 Promise,但您不會更改原始的 Promise var。 做
if (!(promise instanceof Promise)) {
promise = Promise.resolve(promise);
}
編輯:在@Ivan Kleshnin 評論之后是根據規范的並行解決方案:
Promise.all = async function (array) {
const results = [];
parllalLoopFinish = () =>{
return results.length === array.length;
}
return new Promise((resolve,reject) =>{
for (let index = 0; index < array.length; index++) {
const promise = array[index];
if(promise instanceof Promise){
promise.then((value)=>{
results[index]=value;
if(parllalLoopFinish()) {
resolve(results);
}
}).catch(reject)
}
else{
results[index]=promise;
}
}
if(parllalLoopFinish()) {
resolve(results);
}
});
};
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
Promise.all([promise1, promise2, promise3]).then((res) => console.log(res));
因為您試圖在 p2 上調用then()
,這是一個數字。
這是我實現Promise.all()
的方式
編輯:舊的迭代解決方案
Promise.all = async function (array) {
const results = [];
for (let index = 0; index < array.length; index++) {
try {
const value = await Promise.resolve(array[index]);
results.push(value);
} catch (error) {
return Promise.reject(error);
}
}
return Promise.resolve(results);
};
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "foo");
});
Promise.all([promise1, promise2, promise3]).then((res) => console.log(res));
// print [3, 42, 'foo']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.