[英]Array of promise with results separately
基本上,我正在尋找類似Promise.all()
東西,但是只要結果准備好,就會在每個結果中調用then()
的函數。 使用像這樣的標准回調(文件讀取示例)來編寫它是微不足道的:
function foo(files, bar) {
for (let file of files) {
const fr = new FileReader();
fr.onload = e => bar(e.target.result);
fr.readAsDataURL(file);
}
}
我確定那里有一個庫可以滿足我的需要,但我想在純JS中做到這一點。
為了澄清,我希望有這樣的事情:
function foo(files) {
// do something here;
}
foo(['1','2','3']).then(/* do something here with separate results */);`
只需使用map
:
let read = file => return new Promise(resolve => {
const fr = new FileReader();
fr.onload = e => resolve(e.target.result);
fr.readAsDataURL(file);
});
Promise.all(files.map(file => read(file).then(bar)))
.then(allResultsFromBar => { /* use results array */ });
需要注意的是.then
促進從它執行的承諾函數返回(即它調用任何Promise.resolve
它隱含的),所以Promise.all
是保證收到承諾的數組不管是什么bar
回報。
使用@ jib的答案和評論:
我想要一個函數readFiles,它將一個文件列表作為唯一的參數,我希望它返回一些我可以調用then()的承諾,並且我將放入then()的函數將是為每個文件單獨調用。
這是不太可能的,因為.then()
回調只被調用一次,而不是每次由Promise.all()
傳遞的結果。
這很接近:
let read = file => return new Promise((resolve, reject) => {
const fr = new FileReader();
fr.onload = e => resolve(e.target.result);
fr.onerror = reject; // don't forget to reject on error
fr.readAsDataURL(file);
});
let readFiles = files => return Promise.all(files.map(read)); // <<<<< this is the line you seek
允許你寫:
const files = ["...", "...", "..."];
readFiles(files)
.then(allFileResults => allFileResults.map(bar)); // bar is your function for processing file results
// possibly chain another .then() if required to observe/process bar()'s results
因此bar()
將依次對每個文件內容進行操作。
但是,在使代碼盡可能接近您的要求時:
allFileContents.map(bar)
進程是Promise.all()
下游,因此在開始執行bar()
調用之前等待讀取所有文件。 readFiles(...)
任何單個錯誤(沒有某種錯誤恢復)都會導致整個企業陷入readFiles(...)
; 永遠不會在任何文件上調用allFileContents.map(bar)
; 根據您的申請,這可能是好的或壞的; 雖然好消息,但很容易插入錯誤恢復。 bar()
必須是同步的; 如果沒有,你可以簡單地插入另一個Promise.all()
,即allFileResults => Promise.all(allFileResults.map(bar))
。 出於這些原因,@ jib的解決方案可能是最好的解決方案,但這取決於應用程序的要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.