【问题标题】:Delay the foreach Loop in Node JS延迟 Node JS 中的 foreach 循环
【发布时间】:2020-09-15 09:30:31
【问题描述】:

希望你一切安好。我从一个 API 获取数据并发送到 Shopify 商店 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)
          
          });
          
      
          }

);



}




);

【问题讨论】:

  • 希望你知道 JS 本质上是异步的,你需要 callback/promise/async-await 使其同步

标签: javascript node.js api foreach


【解决方案1】:

您不需要使用 setTimeOut() 来延迟循环。这就是 async 和 await 的用途,让我分享一个示例,如何使用 await 进行 forEach 循环延迟!!。 step1 : 返回一个带有 promise 的函数并使用 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. 请求是deprecated
    2. 无论如何都不能和await一起使用,很不方便。曾经有另一个模块 request-promise,它包装 request 并返回一个 Promise,所以可以 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)
      

      这会在 10 秒后执行 forEach。

      【讨论】:

      • 嗨 Dharman,感谢您的评论,但我应用了此代码并得到以下错误结果“internal/validators.js:189 throw new ERR_INVALID_CALLBACK(callback); ^ TypeError [ERR_INVALID_CALLBACK]: Callback must be一个函数。收到未定义的"
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      • 1970-01-01
      • 2017-03-10
      相关资源
      最近更新 更多