Задержка цикла foreach в узле JS

#javascript #node.js #api #foreach

#javascript #node.js #API #foreach

Вопрос:

Я надеюсь, что у вас все хорошо. Я получаю данные из одного API и отправляю в Shopify store API. Поскольку он работает нормально, но вводит некоторые продукты, так как при итерации в цикле API занят индексом, предположим, 0,1,2, а затем обходятся индексы 3,4, … 10. Итак, по моему мнению, я должен отложить цикл foreach на 10,15 секунды. Пожалуйста, помогите мне сделать это. Я много раз пробовал это с помощью SetTimer и т.д., Но структура цикла foreach сложна для меня как для нового человека. Пожалуйста, проверьте приведенный ниже код. Спасибо

 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)
          
          });
          
      
          }

);



}




);
  

Комментарии:

1. надеюсь, вы знаете, что JS асинхронен по своей природе, вам понадобится обратный вызов / обещание / async-await, чтобы сделать его синхронным

Ответ №1:

вам не нужно использовать setTimeout() для задержки цикла. вот для чего нужны async и await позвольте мне поделиться с вами примером того, как сделать задержку цикла forEach с помощью await !!. шаг 1: верните функцию с обещанием и используйте await до ее завершения.

     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');
  

})

Ответ №2:

  1. Запрос устарел
  2. В любом случае его нельзя использовать с await , что делает его неудобным. Раньше был другой модуль, request-promise, который обертывал request и возвращал обещание, поэтому можно было await использовать его, но он все еще устарел.
  3. По этим причинам вместо этого используйте Axios или Fetch
  4. Вы не можете использовать await или задерживать .forEach() цикл, но вы можете в for цикле.
  5. Вы думаете, что вам нужно отложить вызовы, потому что они асинхронны, но на самом деле вы должны просто ожидать каждого вызова. Задержка вызовов с произвольным таймаутом — это грязный обходной путь.

В конце концов, вы можете сделать что-то вроде :

 ( 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
    }
})()
  

Ответ №3:

 setTimeout(pro.rows.forEach((row) => {...}), 10000)
  

Это выполняет forEach через 10 секунд.

Комментарии:

1. Привет, Дхарман, спасибо за комментарий, но я применил этот код и получил следующие результаты ошибки «internal/ validators.js:189 выдает новую ошибку ERR_INVALID_CALLBACK (обратный вызов); ^ TypeError [ERR_INVALID_CALLBACK]: обратный вызов должен быть функцией. Получено неопределенное»