Reputation: 323
Trying to add a small delay to each http.request in NodeJS but of course node always goes in sync mode. So the question is how do I reset the state of a promise once it's been fulfilled?
Tried the default set timeout inside the promise, wrapped http.request with a new setTimeout promise, tried using an external "requestHandler" as a callback, which was running the function as a thennable. etc.etc Perhaps I have to clearTimeout? https://nodejs.org/api/timers.html
exports
const wait = require("util").promisify(setTimeout);
module.exports = {
delay: async function(seconds){
await wait(seconds * 1000);
},
getUrl: function(url){
return new Promise((resolve, reject) => {
const options = new URL(url);
const resolver = http.request(options, res => {
res.setEncoding("utf8");
let responseBody = '';
res.on("data", body => {
responseBody += body
});
res.on('end', () => resolve(responseBody));
});
resolver.end();
});
}
};
app
const helper = require("./exports.js");
async function getdata(url) {
const data = await help.getUrl(url);
let results = JSON.parse(data);
results = results.answer;
return results;
}
function fetchData(el, i) {
getdata(el).then(
answer => { console.log(answer)},
//...etc
)
}
function getLinksFromFile(file) {
helper.readFile(file)
.then(arr => {
arr.forEach((el, i) => {
/////////ISSUE HERE BELOW//////////////
helper.delay(4).then(() => {
////It only waits once
return fetchData(el, i);
});
});
});
}
getLinksFromFile("./links.txt");
The objective is as simple as it can get, read urls form file, get json data from the url's and do stuff. Dependency Free
Upvotes: 0
Views: 1106
Reputation: 40842
You need to do some more reading about how promises work or do some more experiments with Promises, to understand them better.
So what does this code do:
arr.forEach((el, i) => {
/////////ISSUE HERE BELOW//////////////
helper.delay(4).then(() => {
////It only waits once
return fetchData(el, i);
});
});
You iterate over each element of arr
and for each of them you create a Promise for the delay using helper.delay(4)
. But all of those Promises are created at roughly the same time (just some nanoseconds apart), because the forEach does not wait for the one Promise chain to be finished. So each fetchData
is delay by 4second form the time when forEach
happened.
The easiest way to solve that problem is to convert your code to use await
/async
syntax:
async function getLinksFromFile(file) {
let arr = await helper.readFile(file);
for( let i=0, i<arr.length ; i++) {
let el = arr[i];
await helper.delay(4)
await fetchData(el, i)
}
}
Using await
in a regular loop will pause the loop at that point until the Promise is resolved.
Upvotes: 1