Reputation: 4766
I have a loop. I am performing following tasks within the loop.
I need to add a delay between these two tasks due to the slowness of the web service. I use a setTimeout
in between these two tasks. Problem is the execution order of each task. When I log the output of each task, I can see it first prints all file content read from files then "Delayed" messages(n times) and then responses from service calls. According to the console output
[File 1 content]
[File 2 content]
[File 3 content]
Delayed
Delayed
Delayed
[Service response for File1]
[Service response for File2]
[Service response for File3]
seems like these three tasks are executed parallelly but not sequentially. My goal is to execute them sequentially.
What is the problem in my code which results above behavior
Following is my code
function myFunction() {
console.log("Delayed");
}
filenames.forEach(function (filename) {
fs.readFile(dir + filename, 'utf8', function(err, fileContent) {
console.log(fileContent);
setTimeout(myFunction, 3000);
anotherAsyncServiceCall(fileContent, function (err, response) {
.....
)};
}
Upvotes: 0
Views: 52
Reputation: 169
Make your function an async
function and set await
to asynchronous tasks.
function myFunction() {
console.log("Delayed");
}
let contents = [];
let responses = [];
const fileReading = async (filename) => {
const content = await fs.readFileSync(dir + filename, 'utf8');
contents.push(content);
}
const getResponse = async (content) => {
const response = await anotherAsyncServiceCall(content);
responses.push(response);
}
filenames.forEach(async function(filename) {
await fileReading(filename);
});
contents.forEach(async function(content) {
await getResponse(content);
});
You can get your responses from responses
array.
Upvotes: 1
Reputation: 1313
There are different ways by which you can achieve what you are trying to do.
Using Promise as return
fs.readfile(dir + filename, 'utf8',function(err, fileContent){
if(err) throw err;
return anotherAsyncServiceCall(fileContent);
}).then(function(err, response){
if(err) throw err;
//return the response or do any thing
}).catch(function(exception){
console.log('exception occured',exception);
});
List all the promise and then execute them all at once using Promise.all()
//creating a global variable to contain our promises
var promiseList =[];
filenames.forEach(function (filename) {
var fileContent= fs.readFileSync(dir + filename, 'utf8');
promiseList.push(anotherAsyncServiceCall(fileContent));
});
and then use the Promise.all()
to execute all the promises:
Promise.all(promiseList).then(function(err,response) {
console.log(response);
});
using async - await
fs.readfile(dir + filename, 'utf8',async function(err, fileContent){
if(err) throw err;
var response = await anotherAsyncServiceCall(fileContent);
return response;
}).catch(function(exception){
console.log('exception occured',exception);
});
Update the fs.readFile is not a promise but is async so it supports the callback.
Upvotes: 1