我认为这是一个常见的问题,但具体情况是:
我使用mammoth模块将docx
个文件转换为html
。该模块返回promise
我有一个文件数组,当我使用循环为每个文件创建一个promise时,我需要知道什么promise会返回一个结果(知道处理了哪个文件)。
for(var i=0;i<filesPaths.length;i++){
mammoth.convertToHtml( {path: filesPaths[i]} )
.then(function(result){
filesHtml.push(result.value);
//here I need to know the value of filesPaths[i]
})
}
答案 0 :(得分:2)
在撰写问题时,答案变得明显(通常情况:): 您可以使用自调用函数包装promise,并将任何相关信息存储在局部变量中。
for(var i=0;i<filesPaths.length;i++){
(function(){
var fileName = filesPaths[i]; //or any other information related to promise
mammoth.convertToHtml( {path: filesPaths[i]} )
.then(function(result){
filesHtml.push({
text:result.value,
fileName:fileName
});
})
})()
}
答案 1 :(得分:1)
您可以使用.map()数组方法(这与函数调用方面的解决方案非常相似,但更清晰一点):
filesPaths.map(function(fileName, i){
mammoth.convertToHtml({path: fileName})
.then(/* ... */)
;
});
// Here filesHtml is empty and you don't know when will be filled!!
......这很脏(见最后的评论)。
或者你可以简单地使用Promise.all()来收集结果:
var P = Promise.all(
filesPaths.map(function(fileName){
return mammoth.convertToHtml({path: fileName});
})
).then(function(resultArr){
return Promise.all(resultArr.map(function(result, i){
return {
text: text.value,
fileName: filesPaths[i],
};
}));
}).then(function(filesHtml){
/* Here you know filesHtml is fully filled */
});
P.then(function(filesHtml){
/* ...and here too */
});
这样,你也不会弄乱全局(或更高范围)变量。
答案 2 :(得分:0)
用另一种选择回答你自己的答案:
在循环中创建函数不是一个好主意,它是创建未知数量的函数的一种非常好的方法。如果你使用了forEach循环,你将在其回调函数中获得相同的封装。
var arr = ['a', 'b', 'c'];
function prom(thing) {
return Promise.resolve(thing);
}
for (var i = 0; i < arr.length; i++) {
prom(arr[i]).then(function(val){
console.log(`for: got val ${val} with arr[${i}]`);
});
}
// Logs:
// "for: got val a with arr[3]"
// "for: got val b with arr[3]"
// "for: got val c with arr[3]"
arr.forEach(function(val, index) {
prom(val).then(function(val){
console.log(`forEach: got val ${val} with arr[${index}]`);
});
});
// Logs:
// "forEach: got val a with arr[0]"
// "forEach: got val b with arr[1]"
// "forEach: got val c with arr[2]"