【原文連結】 https://segmentfault.com/q/1010000007499416
【注】 原文是一篇問答形式的帖子,此處做了小幅度整理; 本文轉於此處,用於本人收藏,查詢方便之用。如有侵權,請聯絡刪除。
需求是有一個objects陣列,其中的元素是每次非同步事件需要的引數
非同步事件事件接受引數並且序列執行,最終返回一個promise結果
Promise.all似乎是並行的?
const PromiseForEach = (objects, asyncDosometing) => {
return new Promise((resolve, reject) => {
Promise.all(objects.map((obj) => {
return new Promise((resolve, reject) => {
return asyncDosometing(obj).then(resolve, reject);
});
})).then(resolve, reject);
});
};
複製程式碼
這樣寫似乎也是並行的?
const PromiseForEach = (objects,asyncDosometing) => {
let result = Promise.resolve();
objects.forEach((obj) => {
result = result.then(asyncDosometing(obj));
});
return result;
}
複製程式碼
// 測試結果為
// 直接列印了“成功” data為undefined 之後 一次性列印出所有“number”
// 而不是 每隔2s列印一個number number都列印完後 列印成功 並且data應給是個number陣列
const list = [];
for (let i = 0; i < 100; ++i) {
list.push(i);
}
PromiseForEach(list, (number) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(number);
return resolve(number);
}, 2000);
})
}).then((data) => {
console.log("成功");
console.log(data);
}).catch((err) => {
console.log("失敗");
console.log(err)
});
複製程式碼
兩種寫法貌似有有問題呢
到是用async/await實現了
雖然不知道對不對啊 但是實現了預期
const PromiseForEach = async(objects, asyncDosometing) => {
let result = [];
for (let obj in objects) {
try {
result.push(await asyncDosometing(obj));
} catch (err) {
return err;
}
}
return result;
};
複製程式碼
請問用Promise實現這種邏輯的正確的寫法是怎麼樣的?求解!謝謝!!!
下面是社群人士whbb的回答:
第二種方式的正確的
runjs.cn/code/ilckww…
如果需要返回結果的話, 可以再加一層 Promise
const list = [];
for (let i = 0; i < 100; ++i) {
list.push(i);
}
複製程式碼
function PromiseForEach(arr, cb) {
let realResult = []
let result = Promise.resolve()
arr.forEach((a, index) => {
result = result.then(() => {
return cb(a).then((res) => {
realResult.push(res)
})
})
})
return result.then(() => {
return realResult
})
}
PromiseForEach(list, (number) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(number);
return resolve(number);
}, 100);
})
}).then((data) => {
console.log("成功");
console.log(data);
}).catch((err) => {
console.log("失敗");
console.log(err)
});
複製程式碼
下面是一些雜七雜八的
- 我一開始使用Promise時,一直找不到在for迴圈裡面如何使用 promise來控制非同步,並且在 迴圈體外,獲取非同步的結果陣列。
- 直到我看見了這個問答,看見了 let result = Promise.resolve() 這個寫法,我赫然開朗。
用一個Promise物件,將非同步任務執行完成的結果作為引數傳遞,並且通過 在then以後,push結果到一個全域性的陣列裡面,最終獲取到結果。
result = result.then(() => {
return cb(a).then((res) => {
realResult.push(res)
})
})
複製程式碼
- 好吧,不亂說了。)>_<(