简体   繁体   中英

Delay the foreach Loop in Node JS

I hope you are well. I am getting data from one API and sending to Shopify store API. As its working fine but its entering some products as when it iterates in the loop API is busy with index suppose 0,1,2 and then indexes 3,4,...10 bypassed. So , according to me I should delay the foreach loop with 10,15 seconds. Please help me to do this . I tried it many times with SETTimer etc but foreach loop structure is difficult for me as a new person. Please check the below code. Thanks

const request = require('request');
const { json } = require('express');
const { Parser } = require('json2csv');
const fastcsv = require('fast-csv');
//const csv = require('csv-parser');
const fs = require('fs');
const { privateDecrypt } = require('crypto');
const { time } = require('console');



const fields = ['Vendor', 'Price', 'SKU','error'];


const opts = { fields };
 
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
const csvWriter = createCsvWriter({
  path: 'C:/Users/IT City/Desktop/arslan.csv',
  header: [
    {id: 'Vendor', title: 'Vendor'},
    {id: 'Price', title: 'Price'},
    {id: 'SKU', title: 'SKU'},
    {id: 'error', title: 'error'},
  ]
});

let new_products = {
  product_final: {
    Vendor: String,
    Price: String,
    SKU: String,
    Error: String,
  }
};
//////////First API from which I am getting the data

const options = {
  method: 'GET',
  url: 'https://api.dexi.io/runs/f58f7795-c11a-478c-b670-c7ae5df8677b/latest/result',
  headers: {
    accept: 'application/json',
    json: true,
    'x-dexiio-access': '9d56e967dfXXXXXXX725e234b311655c96',
    'x-dexiio-account': '5e597feb-99axxxxxxxx-37f1315723ab'
  }
};




products = ['Vendor','Price','SKU','Error']
let product = {};
request(options, function (error, response, body) {
  if (error) throw new Error(error);
  pro = JSON.parse(body);
 
/////Looping through the each Item from the first API and sending data to Shopify. But its entering only 10-12 products 
//// As handle is busy to entering the product.
/// I have to delay the foreach loop 10, 15 seconds

pro.rows.forEach(       
  
  row => { 
    
    
        for (let z = 0; z < row.length; z++) 
        {
            product[pro.headers[z]] = row[z];
            product_final2[pro.headers[z]] = row[z];
        }
         
      
        productssdata.push(product_final2)
        
        products.push(product)
       
        var Price = product.Price;
        var SKU = product.SKU;
        var Vendor = product.Vendor;
        var body_html = "THISFSDFSDFSDFSDFSFSDF";

        
            
             let new_products = {
              product: {
                title: Vendor,
                body_html: Price,
                vendor: Vendor,
                product_type: SKU,
                tags: Price
              }
            };
                    
            const options = {
            
            method: 'POST',
            url: 
            'https://0abcfsdfsdf4bb6532f3b@amjad.myshopify.com/admin/api/2020-07/products.json',
            headers: {
            accept: 'application/json',
            'apiKey': '07649cABSDCCSD8ffbae7af02',
            'password': 'sSDCSDFDF',
            body: new_products,
            json: true,
            
            };
         
          request(options, function (error, response, body) {
          
          if (error) throw new Error(error);
          console.log(body)
          
          });
          
      
          }

);



}




);

you don't need to use setTimeOut() to delay the loop. thats what async and await are for let me share you an example how to make the forEach loop delay with await!!. step1 : return a function with promise and use await until it is complete.

    const wait =async props => {
    return new Promise((reslove,reject) => {
    return reslove(Math.random());       
})

}

       const x = [1,2,3,4]
       x.forEach(async number =>{
       const num = await wait();
       console.log('start')
       console.log(num);
       console.log('end');

})

  1. Request is deprecated
  2. It can't be used with await anyway, which makes it inconvenient. There used to be another module, request-promise , that as wrapping request and return a Promise, so one could await it, but it's still deprecated.
  3. For these reasons, use Axios or Fetch instead
  4. You can't use await or delay a .forEach() loop, but you can in a for loop.
  5. You think you need to delay the calls, because they are asynchronous, but in reality you should simply await each call. Delaying calls with an arbitrary timeout is a dirty workaround.

In the end, you can do something like :

( async () => {

    let options = {
        url : "http://......"
    };

    const response = await axios.get(options); // Add try/catch block around this to manage errors

    const pro = response.data;

    for( let row of pro.rows) {

        options = {
            url : "http://some.other.url"
        }

        const response = await axios.get(options); // Each call will be done one by one and awaited in order
    }
})()
setTimeout(pro.rows.forEach((row) => {...}), 10000)

这将在 10 秒后执行 forEach。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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