简体   繁体   English

承诺循环。 如何检测哪个承诺现在返回结果?

[英]Loop of promises. How to detect which promise returns the result now?

I think it's a common question, but for concreteness the situation is: 我认为这是一个常见的问题,但具体情况是:
I use the mammoth module to convert docx files to html . 我使用庞大的模块将docx文件转换为html The module returns a promise . 该模块返回一个promise
I have an array of files and when I use a loop to create a promise for every file I need to know what promise returns me a result (to know what file was processed). 我有一个文件数组,当我使用循环为每个文件创建一个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]
        })
}

While writing the question, the answer became obvious (as is often the case :) ). 在撰写问题时,答案变得明显(通常情况:)。
You can wrap the promise with a self invoked function and store any related info in local variable. 您可以使用自调用函数包装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
                         });

        })
    })()
}

You can use .map() array method (which is much like your solution in terms of function calls, but a bit cleaner): 您可以使用.map()数组方法(这与函数调用方面的解决方案非常类似,但更清晰一点):

filesPaths.map(function(fileName, i){
  mammoth.convertToHtml({path: fileName})
    .then(/* ... */)
  ;
});
// Here filesHtml is empty and you don't know when will be filled!!

...which is dirty (see the comment at the end). ......这很脏(见最后的评论)。

Or you can simply use Promise.all() to collect the results: 或者你可以简单地使用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 */
});

This way, you also aren't messing things with global (or higher scope) variables. 这样,您也不会弄乱全局(或更高范围)变量。

To respond to your own answer with an alternative: 用另一种方式回答你自己的答案:

Creating functions in loops is not a great idea, it's a pretty good way to an unknown number of functions created. 在循环中创建函数不是一个好主意,它是创建未知数量的函数的一种非常好的方法。 If you used a forEach loop you would get the same encapsulation in its callback function. 如果使用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]"    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在运行一个承诺循环后,如何获取我存储在数组中的数组的数据。 并将该数据导出到另一个节点文件中? - How can I get the data of an array in which I m storing in array after running a loop of promises. And export that data in another node file? 包含承诺的 forEach 循环上的 Promise - Promise on forEach loop which contains promises 未捕获(在承诺中):如何等待在循环内返回承诺的函数? - Uncaught (in promise):How to await a function which returns a promise inside a loop? 茉莉花 - 测试承诺。 如何在回调中测试函数? - Jasmine - testing promises. How to test function in callback? 如何处理依赖于另一个承诺的承诺循环 - How to deal with a loop of promises dependant on another promise While 循环中的承诺,其中 while 的条件基于承诺的结果 - Promises in a While Loop where condition of while is based on result of the promise JS Promise API:创建一个Promise循环并将结果合并到另一个对象中 - JS Promise API: Create a loop of promises and merge result into another object 了解回调和承诺。 这个对吗? - Understanding callbacks and promises. Is this correct? 如何使用循环获得 promise 的结果? - How to a result of a promise using loop? 如何创建一个处理两个诺言然后返回一个诺言的类? - How do I create a class that processes two promises and then returns a promise?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM