Reputation: 427
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?
Upvotes: 0
Views: 1172
Reputation: 10096
You should use 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:
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)
});
Upvotes: 4
Reputation: 29071
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. 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
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()
Upvotes: 1