Nodejs async await for loop - node.js

How can I wait until the function a is complete, but is not working as I expected.
Here is my code:
var start = Date.now();
function a() {
setTimeout(function(){ console.log(Date.now() - start); }, 500);
for(var i=0; i<100; i++) {
console.log(i);
//
}
}
const main = async () => {
await a();
console.log("Done");
};
main().catch(console.error);

You have to return promise when you call await. The await operator is used to wait for a Promise. It can only be used inside an async function. Check here for more details:
async function
var start = Date.now();
function a() {
return new Promise(function(resolve, reject) {
setTimeout(function(){ console.log(Date.now() - start); resolve()}, 500);
for(var i=0; i<100; i++) {
console.log(i);
//
}
})
}
const main = async () => {
await a();
console.log("Done");
};
main().catch(console.error);

var start = Date.now();
function a() {
return new Promise((resolve, reject)=> {
setTimeout(function(){ console.log(Date.now() - start); resolve() }, 500);
for(var i=0; i<100; i++) {
console.log(i);
//
}
});
}
const main = async () => {
await a();
console.log("Done");
};
main().catch(console.error);

you can use q module for make promise also:
var q = require('q')
var start = Date.now();
function a() {
let defer = q.defer()
setTimeout(function(){ console.log(Date.now() - start); defer.resolve();}, 500)
for(var i=0; i<100; i++) {
console.log(i);
}
return defer.promise;
}
const main = async () => {
await a();
console.log("Done");
};
main().catch(console.error);

Related

NodeJS Async/Await or Promise for net-snmp module

please someone help, I just cant get it.
Can you please help on how to make async/await or promise (doneCb), so script waits for first vlc_snmp(..) to finish and then to call next?
Example:
function doneCb(error) {
console.log(final_result);
final_result = [];
if (error)
console.error(error.toString());
}
function feedCb(varbinds) {
for (var i = 0; i < varbinds.length; i++) {
if (snmp.isVarbindError(varbinds[i]))
console.error(snmp.varbindError(varbinds[i]));
else {
var snmp_rez = {
oid: (varbinds[i].oid).toString()
value: (varbinds[i].value).toString()
};
final_result.push(snmp_rez);
}
}
}
var session = snmp.createSession(VLC_IP, "public", options);
var maxRepetitions = 20;
function vlc_snmp(OID) {
session.subtree(OID_, maxRepetitions, feedCb, doneCb);
}
vlc_snmp(OID_SERIAL_NUMBER);
//wait OID_SERIAL_NUMBER to finish and then call next
vlc_snmp(OID_DEVICE_NAME);
You should be able to use the async / await statements to wait for your done callback to be called. We wrap this callback in the vlc_snmp function, and return a Promise. This allows us to use the await statement.
I've mocked out some of the code that I don't have access to, it should behave somewhat similarly to the real code.
The key point here is, when a function returns a Promise we can await the result in an async function, that will give you the behaviour you wish.
final_result = [];
const VLC_IP = "";
const options = {};
const OID_ = "OID_";
const OID_SERIAL_NUMBER = "OID_SERIAL_NUMBER"
const OID_DEVICE_NAME = "OID_DEVICE_NAME"
// Mock out snmp to call feedcb and donecb
const snmp = {
createSession(...args) {
return {
subtree(oid, maxRepetitions, feedCb, doneCb) {
setTimeout(feedCb, 500, [{ oid, value: 42}])
setTimeout(doneCb, 1000);
}
}
},
isVarbindError(input) {
return false;
}
}
function doneCb(error) {
console.log("doneCb: final_result:", final_result);
final_result = [];
if (error)
console.error("doneCb: Error:", error.toString());
}
function feedCb(varbinds) {
for (var i = 0; i < varbinds.length; i++) {
if (snmp.isVarbindError(varbinds[i]))
console.error(snmp.varbindError(varbinds[i]));
else {
var snmp_rez = {
oid: (varbinds[i].oid).toString(),
value: (varbinds[i].value).toString()
};
final_result.push(snmp_rez);
}
}
}
var session = snmp.createSession(VLC_IP, "public", options);
var maxRepetitions = 20;
function vlc_snmp(OID) {
return new Promise((resolve,reject) => {
session.subtree(OID, maxRepetitions, feedCb, (error) => {
// This is a wrapper callback on doneCb
// Always call the doneCb
doneCb(error);
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
async function run_vls_snmp() {
console.log("run_vls_snmp: Calling vlc_snmp(OID_SERIAL_NUMBER)...");
await vlc_snmp(OID_SERIAL_NUMBER);
console.log("run_vls_snmp: Calling vlc_snmp(OID_DEVICE_NAME)...");
//wait OID_SERIAL_NUMBER to finish and then call next
await vlc_snmp(OID_DEVICE_NAME);
}
run_vls_snmp();

Problem to use my Callback function in using "For"?

My code:
console.log('Start')
getMember((member) => { console.log(member) })
console.log('End')
function getMember(next) {
for (let index = 0; index < 1000000000; index++) {
// Simulation setTimeout()
}
next('In getMember')
}
Return:
Start
In getMember
End
I thought I had the following result (see below) but it doesn't, can you explain me?
Return:
Start
End
In getMember
Thanks,
Yves
console.log('Start')
function resolveAfter2Seconds() {
return new Promise(resolve => {
// setTimeout(() => { resolve('resolved') }, 2000);
for (let index = 0; index < 1000000000; index++) { }
resolve('resolved !');
})
};
async function asyncCall() {
console.log('calling');
const result = await resolveAfter2Seconds();
console.log(result);
}
asyncCall();
console.log('End');
Return:
Start
calling
End
resolved !
I have the impression that promises handle callbacks better !

How to add timeout to this async function

I want to add a timeout such that if any of these "tasks" takes longer than 5 minutes, it should stop that function and resolve the promise. I've been struggling a bit, any help is appreciated. Thanks!
if (require.main === module) {
(async () => {
const tasks = [];
for (let i = 1; i <= NB_PARALLEL; i++) {
tasks.push(buildReferenceSpaceCollection(json));
}
const results = await Promise.all(tasks);
console.log(results);
process.exit(0);
})().catch(console.error);
}
You could define a wait-function that rejects after the given amount of time and then use Promise.race on that wait-function and your Promise.all. Now, if your promises inside Promise.all take longer than the wait, Promise.race will reject, otherwise the resolved values will be assigned to results.
function wait(ms) {
return new Promise((_, reject) => {
setTimeout(() => {
reject(new Error("wait time exceeded"));
}, ms);
})
}
(async () => {
const tasks = [];
for (let i = 1; i <= NB_PARALLEL; i++) {
tasks.push(buildReferenceSpaceCollection(json));
}
// 5 mins in ms
const wait5MinPromise = wait(5*60*1000);
const results = await Promise.race([wait5MinPromise, Promise.all(tasks)]);
console.log(results);
process.exit(0);
})().catch(console.error)
;
Just for fun (Live demo):
import { CPromise } from "c-promise2";
const generateYourAsyncTaskHereToAddInQueue= async (value)=> {
console.log(`Inner task started [${value}]`);
await CPromise.delay(1000);
return value;
}
(async () => {
const results = await CPromise.all(function* () {
for (let i = 0; i < 10; i++) {
yield generateYourAsyncTaskHereToAddInQueue(`Task result ${i}`);
}
}, {concurrency: 3}).timeout(5000);
console.log(`results:`, results);
return results;
})().catch(console.error);

Async function but Await doesn't work in NodeJS

here's my function...
exports.createSomeFunc = async (param1, callback) => {
for (var i = 0; i < 10; i++) {
await anotherFunc(param2, function (err, result, request, response) {
console.log(result + i);
});
}
})
For some reason I get "SyntaxError: await is only valid in async function" pointing at the Await line. What am I missing?
Someone asked what am I trying to do? I am trying to have the for loop wait at the function until it finishes before continuing to the next iteration. Here's another example:
exports.anotherFunc = (parm, callback) => {
for (var i = 0; i < 5; i++) {
asyncForEach();
console.log(i);
}
}
async function asyncForEach () {
console.log("in");
await setTimeout(function () {
console.log("out");
}, 100);
}
This body of code returns the following:
0
in
1
in
2
in
3
in
4
out
out
out
out
out
so again the For-loop continues. How do I make the FOR loop wait for result of:
1
in
out
2
in
out
...
You are not waiting for setTimeout to complete. If you want to wait for each setTimeout call to complete in each iteration of for loop. You should use promise inside setTimeout and resolve only when callback is executed.
const myFun = async(parm, callback) => {
for (var i = 0; i < 5; i++) {
console.log(i);
await asyncForEach();
}
}
function asyncForEach() {
return new Promise((resolve) => {
console.log("in");
setTimeout(function() {
console.log("out");
return resolve();
}, 100);
})
}
myFun();
the await is used for promise.
const anotherFunc = async (oarams, callback) => {
for (var i = 0; i < 5; i++) {
await asyncProcess();
console.log(i)
}
}
function asyncProcess() {
return new Promise(async (resolve) => {
console.log("in");
await delay(100)
resolve(true)
})
}
const delay = ms => new Promise((resolve) =>setTimeout(() => {
console.log("out")
resolve(true)
}, ms));
anotherFunc();

node promise loop returning promise not working

I'm new to node, playing with promise loops
on completion of my loop (10 iterations) I want to know that the function has completed, how do I do this?
here is my code
var promise1 = new Promise((resolve, reject) => {
for (let i = 0, p = Promise.resolve() ; i < 10; i++) {
p = p.then(_ =>
new Promise(resolve => {
setTimeout(function () {
console.log(i);
resolve();
}, 50);
}
));
}
});
//start
promise1.then(function (result) {
// Resolve
console.log("done");
}, function (result) {
// Reject
console.error(result);
});
promise1 never completes because you forgot to call resolve() or reject() for it.
Please check the code snippet below. I added comments before the lines I added or changed.
// Use different names for the `resolve` callbacks to be clear which is which
var promise1 = new Promise((res) => {
// Move the declaration of `p` outside the loop to let it be visible after the loop
let p = Promise.resolve();
for (let i = 0; i < 10; i++) {
p = p.then(_ =>
new Promise(resolve => {
setTimeout(function () {
console.log(i);
resolve();
}, 50);
}
));
}
// Chain the completion of the outer promise when `p` resolves
p.then(() => res());
});
//start
promise1.then(function (result) {
// Resolve
console.log("done");
}, function (result) {
// Reject
console.error(result);
});
If you want to resolve multiple promises at a time you can use Promise.all.
What you can do is put every promise into array and resolve by using Promise.all function like below.
var promises = [];
for (let i = 0, i < 10; i++) {
promises.push(new Promise.resolve(i));
}
var results = Promise.all(promises);
console.log(results);
function abc() {
return new Promise(function (resolve, reject) {
var events = [];
for(var i=0;i<5;i++) {
var event_arr = {};
var event_city = {};
event_arr.event_city = {"city":"m-"+i};
events.push(event_arr);
}
if(events) {
resolve(events)
}else {
reject("NOp");
}
}).then((events)=>{
var p = Promise.resolve()
var events2 = [];
var i=0;
events.forEach(function(element) {
p = p.then(() => {
return new Promise(function (resolve, reject) {
var address_info = {};
var event_arr = {};
var event_city = element.event_city;
event_arr.event_cityy = event_city;
setTimeout(function () {
var address_info = {"address":"B-"+i};
console.log(i);
i++;
event_arr.address_info = address_info;
events2.push(event_arr);
// console.log(events2)
//resolve(events2);
if(events2) {
resolve(events2);
}else {
reject("NOp2");
}
}, 5000)
}).then((events2)=>{
return events2;
});
})
});
return p.then((events2)=>{
return events2;
});
});
}
var v = abc();
v.then(function(events2) {
console.log(events2)
console.log("-------X------------")
})

Resources