#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:
- Запрос устарел
- В любом случае его нельзя использовать с
await
, что делает его неудобным. Раньше был другой модуль, request-promise, который обертывалrequest
и возвращал обещание, поэтому можно былоawait
использовать его, но он все еще устарел. - По этим причинам вместо этого используйте Axios или Fetch
- Вы не можете использовать
await
или задерживать.forEach()
цикл, но вы можете вfor
цикле. - Вы думаете, что вам нужно отложить вызовы, потому что они асинхронны, но на самом деле вы должны просто ожидать каждого вызова. Задержка вызовов с произвольным таймаутом — это грязный обходной путь.
В конце концов, вы можете сделать что-то вроде :
( 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]: обратный вызов должен быть функцией. Получено неопределенное»