Home > database >  How to add await in a for loop to wait for function call?
How to add await in a for loop to wait for function call?

Time:03-29

im a beginner in Javascript / Nodejs.

i want to read a folder, and then each by each call a function with await...

I have a Folder, inside that folder i have Images. with readdir i get all Folder Images with extension.

with that code i read the folder and split the ImageName and the .png, so i have only the ImageName without the .png.

idk if there is a better solution.

fs.readdir(testFolder, (err, files) => {
  files.forEach(file => {
   const split = file.split('.');
   .....split[0]
  });
});

If i add then this code inside the readdir

storeAsset();

Code from storeAsset

async function storeAsset() {
   const client = new NFTStorage({ token: NFT_STORAGE_API_KEY })
   const metadata = await client.store({
       name: 'ExampleNFT',
       description: 'My ExampleNFT is an awesome artwork!',
       image: new File(
           [await fs.promises.readFile('assets/Test.png')],
           'MyExampleNFT.png',
           { type: 'image/png' }
       ),
   })
   console.log("Metadata stored on Filecoin and IPFS with URL:", metadata.url)
}

The Function storeAsset() run without Problem but its not waiting to finish StoreAsset and then each by each.

If i Add await that the forEach loop wait for finish each File...;

await storeAsset();

i get this Message:

await storeAsset();
    ^^^^^

SyntaxError: Unexpected reserved word
←[90m    at ESMLoader.moduleStrategy (node:internal/modules/esm/translators:115:18)←[39m
←[90m    at ESMLoader.moduleProvider (node:internal/modules/esm/loader:289:14)←[39m
←[90m    at async link (node:internal/modules/esm/module_job:70:21)←[39m

So, how i can modify the readdir function with await storeasset that every function call wait for finish and then the next one?

thanks for helping

edit:

i have this now:

    fs.readdir(testFolder, (err, files) => {
  files.forEach(async file => {
   const split = file.split('.');
//
    await storeAsset();
//
   console.log(split[0]);
    //   process.exit(1);
  });
});

but its a bit wrong...

Metadata stored on Filecoin and IPFS with URL: ipfs://xxx/metadata.json
4
Metadata stored on Filecoin and IPFS with URL: ipfs://xxx/metadata.json
5
Metadata stored on Filecoin and IPFS with URL: ipfs://xxx/metadata.json
1
Metadata stored on Filecoin and IPFS with URL: ipfs://xxx/metadata.json
3
Metadata stored on Filecoin and IPFS with URL: ipfs://xxx/metadata.json
2

I need: 1 Image > Upload wait for Return Answer, then 2 Image and so on, and not start every upload at same time and then the upload is mixxed and not 1,2,3,4,5...

CodePudding user response:

This is a generic example to show how asynchronous code can be used along with readdir and a loop

const fs = require("fs")

function pr(f) {
    return new Promise((resolve, _reject) => {
        setTimeout(function () {
            resolve("got file "   f)
        }, 500)
    })
}

const pth = __dirname; // whatever directory path with something in it...

fs.readdir(pth, async (err, files) => {
    // Don't use a forEach syntax as it doesn't support asynchronous code, 
    // it would not throw an error, but the promises won't be 
    // resolved inside the loop with forEach.
    for (const f of files) { 
        const msg = await pr(f);
        console.log(msg)
    }
})

And here is an example that should correspond to your case (it didn't not fully understand where you call the store asset and how you use the files iterator but it should illustrate the point)

fs.readdir(testFolder, async (err, files) => {
    // ...
    for (const file in files) {
        await storeAsset();
    }
    // ...
});

CodePudding user response:

For iterations to wait for the previous one, and the previous one is running something async, you can wait for it using a simple for loop and await.

Array methods like forEach do not have a mechanism to allow them to wait for an async operation to finish before moving onto the next iteration.

Finally, the reason you are getting the SyntaxError: Unexpected reserved word is that the forEach function must be an async function, though that won't solve the problem you're trying to here.

const run = async () => {
  for (const x of list) {
    await do(x)
  }
}

run()
  • Related