how to loop inside promise async await method? - javascript

i wanna make output like this :
kembalian 1: 30000
kembalian 2: 20000
kembalian 3: 10000
kembalian 4: 5000
so after kembalian, there is number, but i wanna make it automaticly
with this code
function beliPromise(uang, harga) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
const kembalian = uang - harga;
let angka = i
for (let i = 0; i <= 10; i++) {
console.log(i)
}
console.log(`kembalian ${angka}: ${kembalian}`);
if (kembalian > 0) {
resolve(kembalian);
} else {
reject(0); // atau bisa reject('uang anda habis bro :(')
}
}, 500)
})
}
async function kembalianAwait() {
try {
const kembalian1 = await beliPromise(50000, 20000);
const kembalian2 = await beliPromise(kembalian1, 10000);
const kembalian3 = await beliPromise(kembalian2, 10000);
const kembalian4 = await beliPromise(kembalian3, 5000);
// const kembalian5 = await beliPromise(kembalian4, 50000);
// return kembalian5;
} catch (err) {
throw err
}
}
kembalianAwait()
how could be ?

You can use "await" in a for loop, for example:
function beliPromise(uang, harga) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
const kembalian = uang - harga;
if (kembalian >= 0) {
resolve(kembalian);
} else {
reject();
}
}, 500)
})
}
let uang = 50000;
async function kembalianAwait() {
const harga = [20000, 10000, 10000, 5000];
try {
for (let i = 0; i < harga.length; i++) {
let kembalian = await beliPromise(uang, harga[i])
console.log(`kembalian ${i + 1}: ${kembalian}`);
uang = kembalian
}
} catch (err) {
console.log(err);
}
}
And note the usage of >=0, I think having the exact amount of money should not result in an Error.

Use a global index variable:
var index = 1
function beliPromise(uang, harga) {
return new Promise(function(resolve, reject) {
const kembalian = uang - harga;
console.log(`kembalian ${index}: ${kembalian}`);
index ++;
if (kembalian > 0) {
resolve(kembalian);
} else {
reject(0); // atau bisa reject('uang anda habis bro :(')
}
})
}
async function kembalianAwait() {
try {
const kembalian1 = await beliPromise(50000, 20000);
const kembalian2 = await beliPromise(kembalian1, 10000);
const kembalian3 = await beliPromise(kembalian2, 10000);
const kembalian4 = await beliPromise(kembalian3, 5000);
// const kembalian5 = await beliPromise(kembalian4, 50000);
// return kembalian5;
} catch (err) {
throw err
}
}
kembalianAwait()

You have a loop, but reference i outside the loop. You need to include the loop's code into the loop:
function beliPromise(uang, harga) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
const kembalian = uang - harga;
for (let i = 0; i <= 10; i++) {
let angka = i
console.log(i)
console.log(`kembalian ${angka}: ${kembalian}`);
if (kembalian > 0) {
resolve(kembalian);
} else {
reject(0); // atau bisa reject('uang anda habis bro :(')
}
}
}, 500)
})
}
async function kembalianAwait() {
try {
const kembalian1 = await beliPromise(50000, 20000);
const kembalian2 = await beliPromise(kembalian1, 10000);
const kembalian3 = await beliPromise(kembalian2, 10000);
const kembalian4 = await beliPromise(kembalian3, 5000);
// const kembalian5 = await beliPromise(kembalian4, 50000);
// return kembalian5;
} catch (err) {
throw err
}
}
kembalianAwait()

Related

How to use Async Await in Node.js

I am new to Scraping.
This is my PDF downloading code.
I want to use Async Await in this code.
I don't know where I have to use async await in my code.
function scrapPdf(config, search_url, message) {
console.log('PDF downloading');
got(search_url).then(response => {
const $ = cheerio.load(response.body);
$('.search-result').find('li > a').each((idx, elem) => {
if($(elem).text().trim() == 'PDF'){
const item = $(elem).attr('href');
pdf_lists.push(item);
}
})
$('ul.pagination').find('li.page-item').each((idx, elem) => {
if($(elem).attr('class').includes('page-item active navigation')){
if($(elem).next().hasClass('page-item navigation')){
scrapPdf(config, $(elem).next('li').find('a').attr('href'), message);
} else {
const search_result_dir = `./${message.date_ini}-${message.date_end}`;
if(!fs.existsSync(search_result_dir)){
fs.mkdirSync(search_result_dir)
}
for(let i = 0;i < pdf_lists.length; i++){
const download = new DownloaderHelper(pdf_lists[i], search_result_dir);
download.on('end', () => console.log('Download Completed'))
download.start();
}
console.log(`${pdf_lists.length} files Downloaded!`);
uploadFile(search_result_dir);
return ;
}
console.log($(elem).next('li').find('a').attr('href'));
}
});
}).catch(err => {
console.log(err);
});
}
Here's one possibility assuming you only want to use async/await on the Promise returned from the .then:
async function scrapPdf(config, search_url, message) {
let response = null
console.log('PDF downloading');
try {
response = await got(search_url);
} catch (err) {
console.log(err);
}
if (response) {
const $ = cheerio.load(response.body);
$('.search-result').find('li > a').each((idx, elem) => {
if($(elem).text().trim() == 'PDF'){
const item = $(elem).attr('href');
pdf_lists.push(item);
}
})
$('ul.pagination').find('li.page-item').each((idx, elem) => {
if($(elem).attr('class').includes('page-item active navigation')){
if($(elem).next().hasClass('page-item navigation')){
scrapPdf(config, $(elem).next('li').find('a').attr('href'), message);
} else {
const search_result_dir = `./${message.date_ini}-${message.date_end}`;
if(!fs.existsSync(search_result_dir)){
fs.mkdirSync(search_result_dir)
}
for(let i = 0;i < pdf_lists.length; i++){
const download = new DownloaderHelper(pdf_lists[i], search_result_dir);
download.on('end', () => console.log('Download Completed'))
download.start();
}
console.log(`${pdf_lists.length} files Downloaded!`);
uploadFile(search_result_dir);
return ;
}
console.log($(elem).next('li').find('a').attr('href'));
}
});
}
}

Retry Async/Await 3 times then display alert, alert not showing

I am trying to run my function 3 times if refreshAppData() returns false or causes an error. However, I cannot get the function to fire again after the initial call.
How can I retry my async / await and show an error after three attempts?
async function tryRefreshAppData(retries) {
const refreshOk = await refreshAppData();
if (!refreshOk && retries > 0) {
return tryRefreshAppData(retries - 1);
}
alert("refreshAppData was unsuccessful")
throw new Error("Failed to load the data correctly");
}
const MAX_NUMBER_OF_TRIES = 3;
const RETRIES = MAX_NUMBER_OF_TRIES - 1;
await tryRefreshAppData(RETRIES);
What you have done seems to already work but you should handle the case where refreshAppData() throw an error. I put an example below :
async function refreshAppData(retries) {
if (retries === 1) {
return Promise.resolve("ok");
}
return Promise.reject("tizzi");
}
async function tryRefreshAppData(retries) {
try {
const refreshOk = await refreshAppData(retries);
if (!refreshOk && retries > 0) {
return tryRefreshAppData(retries - 1);
}
console.log("SUCCESS", refreshOk);
return refreshOk;
} catch (e) {
console.log("ERROR");
if (retries > 0) {
return tryRefreshAppData(retries - 1);
}
throw new Error("Failed to load the data correctly");
}
}
const MAX_NUMBER_OF_TRIES = 3;
const RETRIES = MAX_NUMBER_OF_TRIES;
tryRefreshAppData(RETRIES);
Here's a quick solution (written in TS tho).
you can replace resolve() with reject() in order to test it of course:
const MAX_NUMBER_OF_TRIES = 3;
const RETRIES = MAX_NUMBER_OF_TRIES - 1;
const tryRefreshAppData: (iteration: number) => Promise<void> = (iteration) => new Promise((resolve, reject) => {
setTimeout(() => {
console.log(iteration);
resolve();
}, 1000);
});
async function doAsyncCall() {
const iterations = Array.from({length: MAX_NUMBER_OF_TRIES}, (v,i) => i);
let failedAttempts = 0;
for(const iteration in iterations) {
try {
await tryRefreshAppData(parseInt(iteration));
break;
} catch {
failedAttempts +=1;
}
}
if(failedAttempts === MAX_NUMBER_OF_TRIES) {
alert("refreshAppData was unsuccessful");
}
}
doAsyncCall();
You can use the .catch() method on refreshAppData and return false:
function refreshAppData(retries) {
return new Promise((resolve, reject) => {
setTimeout( function() {
reject("Error!");
}, 750);
})
}
async function tryRefreshAppData(retries) {
console.log('retries', retries);
const refreshOk = await refreshAppData().catch(err => false);
if (!refreshOk && retries > 0) {
console.log('retry');
return tryRefreshAppData(retries - 1);
}
alert("refreshAppData was unsuccessful");
throw new Error("Failed to load the data correctly");
}
const MAX_NUMBER_OF_TRIES = 3;
const RETRIES = MAX_NUMBER_OF_TRIES - 1;
(async function() { await tryRefreshAppData(RETRIES); })()
You could also use try...catch and use the catch block to retry/show an error:
function refreshAppData(retries) {
return new Promise((resolve, reject) => {
setTimeout( function() {
reject("Error!");
}, 750);
})
}
async function tryRefreshAppData(retries) {
console.log('retries', retries);
try {
const refreshOk = await refreshAppData(retries);
} catch(err) {
if (retries > 0) {
console.log('retry');
return tryRefreshAppData(retries - 1);
}
alert("refreshAppData was unsuccessful")
throw new Error("Failed to load the data correctly");
}
}
const MAX_NUMBER_OF_TRIES = 3;
const RETRIES = MAX_NUMBER_OF_TRIES - 1;
(async function() { await tryRefreshAppData(RETRIES); })()

SyntaxError: await is only valid in async function. Unable to Correct it

I am unable to run the following code.
It shows me this error:
SyntaxError: await is only valid in async function
const Prom = async() => {
return new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
};
const final = await Prom();
console.log(final);
You could use IIFE
const Prom = async () => {
return new Promise((resolve, reject) => {
let a = 2
if (a == 2) {
resolve('Its working')
} else {
reject('Its not working')
}
})
}
;(async function() {
const final = await Prom()
console.log(final)
})()
const Prom = async () => {
return new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
};
const final = async () => {
const result = await Prom();
console.log(result);
};
final();
await can only be used inside an async function.
The error here is referring to the final variable. It has to be inside of an async function. Try using the below code.
const prom = new Promise((resolve, reject) => {
let a = 2;
if (a == 2) {
resolve('Its working');
} else {
reject('Its not working');
}
});
(async function() {
const final = await prom;
console.log(final)
})()

Use jest for testing timeouts calling recursive function

I want to test the following code:
const poll = (maxTries, interval, channel, stopTime) => {
let reached = 1;
const someInformation = someGetter();
const fetchData = async (resolve, reject) => {
const data = await networkClass.someApiCall();
if (data.stopTime === 1581516005) {
console.log("cond true");
someInformation.meta1 = transFormer(someInformation);
someInformation.meta2 = transFormer(someInformation);
someInformation.meta3 = {
...someInformation.meta1,
data,
};
resolve(someInformation);
} else if (reached < maxTries) {
reached += 1;
console.log("do it again");
setTimeout(fetchData, interval, resolve, reject);
} else {
reject(new Error('max retries reached'));
}
};
return new Promise(fetchData);
};
const checkForUpdates = () => {
setTimeout(() => {
poll(/* max retries */ 10, /* polling interval */ 1000, channel, stopTime)
.then((res) => {
setData(res);
console.log({ res: res.meta3.data });
})
.catch((e) => console.log({ e }));
}, 20000);
};
The test looks like that:
it(`should do stuff`, () => {
jest.spyOn(networkClass, 'someApiCall')
.mockResolvedValueOnce({ stopTime })
.mockResolvedValueOnce({ stopTime })
.mockResolvedValueOnce({ stopTime: 1581516005 });
checkForUpdates();
jest.advanceTimersByTime(40000);
expect(setDataMock).toHaveBeenCalled();
});
That console.log (console.log("do it again");) is only printed once, as if the test would not be able to call a setTimeout within a setTimeout. Do you have any ideas what might help?

How can i use await, when it's don't recognize?

I'm trying to use await on var application = await SchedulerService().getIssues(issueId)
And it returns the error: SyntaxError: await is only valid in async function
I'm starting in node.js. What can I do to fix it?
I've tried already
Add async before initial function const SchedulerService = await function(){ at line 1
Add async on first return return async () => { where's return { at line 3
import schedulerConf from '../../config/scheduler';
import authConf from '../../config/auth';
import applicationConf from '../../config/application';
import request from 'request';
import schedule from 'node-schedule';
import dateformat from 'dateformat';
let interations = 0;
var serviceRecords = [];
var issueRecords = [];
const SchedulerService = function(){
return {
initialize: async () => {
console.log(`***** Starting Scheduler on ${dateformat(new Date(), "dd/mm/yyyy HH:MM:ss")}`);
var j = schedule.scheduleJob('*/1 * * * *', function(){
console.time('└─ Scheduler execution time');
if(interations === 0){
console.log(`Setting scheduler runtime to full time.`);
}else{
console.log(`------------------------`);
}
interations++;
console.log(`Job execution number: ${interations}.`);
SchedulerService().execute()
.then(response => {
console.log(`└─ Job ${interations} was successfully executed.`);
console.log(`└─ Execution date ${dateformat(new Date(), "dd/mm/yyyy HH:MM:ss")}`);
console.timeEnd('└─ Scheduler execution time');
}).catch(error => {
console.log(`└─ Job ${interations} returned error while executing.`);
});
});
},
execute: async () => {
return SchedulerService().getRecords2Sync()
.then(() => {
SchedulerService().sync().then(() => {
}).catch(error => {console.log({error})});
}).catch(error => {console.log({error})});
},
getRecords2Sync: async () => {
serviceRecords = [];
var options = {
url: `http://localhost:${authConf.serverPort}/application`,
method: 'GET',
headers: {
authorization: `${authConf.secret}`
}
}
return new Promise(function (resolve, reject) {
request(options, function (error, res, body) {
if (!error && res.statusCode == 200) {
const srs = JSON.parse(body);
const response = srs['response'];
for(let i =0;i < response.length;i++){
const { id, info } = response[i];
var status = "";
var issueId = "";
var statusClass = "";
for(let x = 0; x < info.length; x++){
if(info[x].key === "status"){
status = info[x].value;
statusClass = info[x].valueClass;
}
if(info[x].key === applicationConf.fields.issueId){
issueId = info[x].value;
}
}
if(statusClass === 0){
if(issueId !== null && issueId !== ""){
serviceRecords.push({id, status, issueId});
}
}
}
//console.log(serviceRecords);
resolve(serviceRecords);
} else {
//console.log(error);
reject(error);
}
});
});
},
getIssues : async (issueId) => {
issueRecords = [];
return new Promise(function(resolve, reject) {
var options = {
url: `http://localhost:${authConf.serverPort}/application2/${issueId}`,
method: 'GET',
headers: {
authorization: `${authConf.secret}`
}
}
request(options, function(error, res, body) {
if (!error && res.statusCode == 200) {
const issues = JSON.parse(body);
const { issue } = issues.response;
const { id, status, custom_fields } = issue;
issueRecords.push({id, status, custom_fields});
resolve(issueRecords);
} else {
reject(error);
}
});
});
},
sync : async () => {
return new Promise(function(resolve, reject) {
for (let i = 0; i < serviceRecords.length; i++) {
const application_id = serviceRecords[i].id;
const application_status = serviceRecords[i].status;
const application_issueId = serviceRecords[i].issueId;
//console.log('issueRecords.length: ', issueRecords);
//console.log('issueRecords.length: ', issueRecords.length);
console.log(`********** application`);
console.log(`└─ id ${application_id}`);
console.log(`└─ status ${application_status}`);
console.log(`└─ issueId ${application_issueId}`);
var application2 = await SchedulerService().getIssues(application_issueId)
.then(response => {
resolve(() => {
console.log(`i've found a record by issue_id ${application_issueId}`);
});
}).catch(error => {
reject(error);
});
}
});
}
}
}
export default new SchedulerService();
Thank you so much!
If you had getIssues resolve with issueId and issueRecords you might do something like this in sync:
sync: async () => {
// `map` over the serviceRecords and return a getIssues promise for each issueId
const promises = serviceRecords.map(({ issueId }) => SchedulerService().getIssues(issueId));
// Wait for all the promises to resolve
const data = await Promise.all(promises);
// Loop over the resolved promises and log the issueId
data.forEach((issueId, issueRecords) => console.log(issueId));
}

Categories

Resources