简体   繁体   English

在循环内调用异步函数

[英]Calling async function inside a loop

I have the following function: 我有以下功能:

function ipfsRetrieve( ipfsHash ){
  return new Promise( function( resolve, reject ) {
    ipfs.catJSON( ipfsHash, (err, result) => {
        if (err){                
            reject(err);
        }
        resolve( result);           
    });
});    

} }

Now, when I call this function inside a loop as below: 现在,当我在如下循环中调用此函数时:

var hashArray   = [ "QmTgsbm...nqswTvS7Db",
                "QmR6Eum...uZuUckegjt",
                "QmdG1F8...znnuNJDAsd6",                    
              ]

var dataArray   = []; 
hashArry.forEach(function(hash){
    ipfsRetrieve( hash ).then(function(data){
        dataArray.push(data);
    });
});  

return dataArray

The "return dataArray' line returns an empty array. How should I change this code to have the "dataArray" filled with the data retrived from IPFS? “ return dataArray”行返回一个空数组。如何更改此代码以使“ dataArray”填充有从IPFS检索的数据?

You should use Promise.all . 您应该使用Promise.all

Construct an Array of Promises and then use the method to wait for all promises to fulfill, after that you can use the array in the correct order: 构造一个Promises数组,然后使用该方法等待所有Promise兑现,然后您可以按正确的顺序使用该数组:

 let hashArray = ["QmTgsbm...nqswTvS7Db", "QmR6Eum...uZuUckegjt", "QmdG1F8...znnuNJDAsd6", ] // construct Array of promises let hashes = hashArray.map(hash => ipfsRetrieve(hash)); Promise.all(hashes).then(dataArray => { // work with the data console.log(dataArray) }); 

For starters, you need to return after rejecting, or else your resolve will get called too. 对于初学者,您需要在拒绝后返回,否则您的解决方案也会被调用。

function ipfsRetrieve( ipfsHash ){
  return new Promise( function( resolve, reject ) {
    ipfs.catJSON( ipfsHash, (err, result) => {
        if (err){                
           reject(err);
           return;
        }
        resolve( result);           
    });
});   

Now for the loop, use map instead of forEach, and return the promise. 现在进行循环,使用map代替forEach并返回promise。 Then wait on the promises. 然后等待诺言。

let promises = hashArry.map(hash=> return new Promise(resolve,reject) { // your code here handling hash, updating theData, and then resolving })
return Promise.all(promises).then( ()=> return theData)

In your case, the promise is provided by ipfsRetrieve, so you would call 在您的情况下,promise由ipfsRetrieve提供,因此您将调用

let promises = hashArry.map(ipfsRetrieve)
return Promise.all(promises)

The caller of your functions will do this: 函数的调用者将执行以下操作:

ipfsRetrieve().then(data=>{ // process data here } )

If you are cool with async await, do this. 如果您对异步等待很满意,请执行此操作。 (marking containing function as async) (将包含功能的标记为异步)

let data = await ipfsRetrieve()

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM