Leave async timer - javascript

First of all I'm sorry I'm a very beginner in JS. The following code stucks at the third line. In the background_mine method. I don't have access to this method, so how can I reset the code after 2 minutes stucking in this method
Mining = async () => {
console.log(`## rebalance: ${await getBalance(account, wax.api.rpc)}`);
let mine_work = await background_mine(account)
}

You may need to do a Promise.race
Example working properly:
const background_mine = new Promise(function(resolve, reject) {
setTimeout(() => resolve('background_mine'), 500);
});
const limitChecker = new Promise(function(resolve, reject) {
setTimeout(() => resolve('background_failed'), 1000);
});
const result = await Promise.race([background_mine, limitChecker])
.catch((error) => {
console.log(`This timed out`);
});
console.log(result); //background_mine
Example having a timeout:
const background_mine = new Promise(function(resolve, reject) {
setTimeout(() => resolve('background_mine'), 500);
});
const limitChecker = new Promise(function(resolve, reject) {
setTimeout(() => resolve('background_failed'), 1000);
});
const result = await Promise.race([background_mine, limitChecker])
.catch((error) => {
console.log(`This timed out`);
});
console.log(result); //undefined
If you check, it all depends on wether background_mine functions is below or above the limitChecker timeout value.

In order to implement a timeout, you can use Promise.race like this:
const background_mine = account => new Promise(() => {});
const promisifiedTimeout = new Promise((resolve, reject) => setTimeout(() => reject('Timed out'), 5000));
(async () => {
const account = {};
try {
const result = await Promise.race([background_mine(account), promisifiedTimeout]);
}
catch(e) {
console.log(e);
}
})();

Related

How to call HttpException in setTimeout, when i wait promise a long time?

I get products from different servers, I want return exception, when wait a long time.
I have created setTimeout for this, but it stoped server and didn't return error.
How to fix it?
const server = 23;
const productsTimeout = setTimeout(() => { throw new HttpException('Problem', HttpStatus.INTERNAL_SERVER_ERROR) }, 3000);
products = await new Promise((resolve, reject) => {
this.socketClientCabinet.on('products_get', async ({ server, products }) => {
if (server === serverID) {
const {
productsSymbols,
} = this.productsTransform(products);
clearTimeout(productsTimeout);
resolve(productsSymbols);
}
});
});
User delete his answer, I have fixed it.
let productsTimeout;
const timeoutPromise = new Promise((res, rej) => {
instrumentsTimeout = setTimeout(() => rej(new HttpException('problem', 500)), 1000, )
})
const productsPromise = new Promise((resolve, reject) => {
this.socketClientCabinet.on('products_get', async ({ server, products }) => {
if (server === serverID) {
const {
productsSymbols,
} = this.productsTransform(products);
clearTimeout(productsTimeout);
resolve(productsSymbols);
}
});
});
const products = await Promise.race([
timeoutPromise,
productsPromise
])
It is work.

Async operations when instance created

I had a job interview yesterday, and I was given a coding challenge as the following:
// 3. Coding challenge.
// The goal is to make function1/function2 to work only when the constructor has finished its async operations.
// You CAN'T change the notifyUrls function. Imagine it's a 3th party library you don't have control on.
// CAN'T CHANGE THIS.
//===================
function notifyUrls(item, callback) {
asyncOperation(item).then((res) => {
callback(res);
});
}
//===================
const asyncOperation = () => { return new Promise((resolve, reject) => { setTimeout(() => { console.log('Timeout execute'); resolve(); }, 2000); }); };
const URL1 = 'http://www.somerestapi/get1';
const URL2 = 'http://www.somerestapi/get2';
const URL3 = 'http://www.somerestapi/get3';
class MyClass {
constructor() {
[URL1, URL2, URL3].forEach(item => {
notifyUrls(item, () => { });
});
}
myFunction1() {
// Only start working when constructor finished notifying.
// ...
console.log('myFunction1');
}
myFunction2() {
// Only start working when constructor finished notifying.
// ...
console.log('myFunction2');
}
}
And here is what I did:
// CAN'T CHANGE THIS.
//===================
function notifyUrls(item, callback) {
asyncOperation(item).then((res) => {
callback(res);
});
}
//===================
const asyncOperation = () => { return new Promise((resolve, reject) => { setTimeout(() => { console.log('Timeout execute'); resolve(); }, 2000); }); };
const URL1 = 'http://www.somerestapi/get1';
const URL2 = 'http://www.somerestapi/get2';
const URL3 = 'http://www.somerestapi/get3';
class MyClass {
constructor() {
this.ready = Promise.all([URL1, URL2, URL3].map((url) => { this.myAsyncCall(url); }));
}
myAsyncCall(item) {
return new Promise((resolve, reject) => {
notifyUrls(item, (res) => { resolve(res); });
});
}
async myFunction1() {
if (await this.ready) {
// Only start working when constructor finished notifying.
// ...
console.log('myFunction1');
}
}
myFunction2() {
// Only start working when constructor finished notifying.
// ...
console.log('myFunction2');
}
}
(async () => {
const myClass = new MyClass();
await myClass.myFunction1();
})();
But the output is:
myFunction1
Timeout execute
Timeout execute
Timeout execute
What I want the output to be is:
Timeout execute
Timeout execute
Timeout execute
myFunction1
How can I work around it?
Thanks.
The problem is in
this.ready = Promise.all([URL1, URL2, URL3].map((url) => { this.myAsyncCall(url); }));
Your map callback doesn't return anything
Either do
this.ready = Promise.all([URL1, URL2, URL3].map((url) => { return this.myAsyncCall(url); }));
or
this.ready = Promise.all([URL1, URL2, URL3].map((url) => this.myAsyncCall(url)));
Adding some coding tips
notifyUrls(item, (res) => {
resolve(res);
});
Can simply be
notifyUrls(item, resolve);
and
const asyncOperation = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 2000);
});
};
is just
const asyncOperation = () => new Promise(resolve => setTimeout(resolve, 2000));

How to get all promises in map with timeout inside

I am trying to get all the results from a map with time out.
I’ve tried to use promise.all() But it didn’t succeed because of the setTimeout function.
I will be happy if someone can look oh my code and suggest how to do it right.
Thank you very much.
new Promise(async (resolve, reject) => {
Promise.all(
items.map(async (item, i) => {
await setTimeout(async () => {
return await SendMail(item);
}, 5000 * i);
})
).then((mailsRes) => {
resolve(mailsRes);
});
});
Simply loop through your items and sleep for x seconds (5 in this example) after sending each email.
const sleep = (milliSeconds) => {
return new Promise((resolve, _reject) => {
setTimeout(() => {
resolve()
}, milliSeconds)
})
}
const sendEmails = async (items) => {
for (let i = 0; i < items.length; i++) {
const currentItem = items[i];
await SendMail(currentItem);
await sleep(5000)
}
}
as you see sendEmails is an async function then you can call it by:
await sendEmails(items)
Not sure what you are trying to achieve but you probably need this-
async function timeout(interval) {
return new Promise(resolve => {
setTimeout(resolve, interval);
});
}
new Promise( async (resolve, reject) => {
Promise.all(items.map( async (item, i)=>{
await timeout(5000 * i).then(() => {
return await SendMail(item);
});
}))
.then(mailsRes => {
resolve(mailsRes)
})
});
The problem is that setTimeout is resolved immediately and you get a timeout canceller in the next callback.
If I understand you correctly, that might do the trick:
function delayedSendMail(item, i) {
return new Promise(resolve => setTimeout(() => resolve(SendMail(item)), 5000 * i));
}
Promise.all(items.map((item, i) => delayedSendMail(item, i)))
.then(mailResults => {
// handle results
});

Iterate in generator

I have a few promises that I have to iterate with the generator. I created the helper function that prints the first promise but I have difficulties creating an iterator in a helper function to iterate all promises. I actually don't understand how constant a, constant b, and constant c can be iterated.
const asyncTask1 = () => new Promise((resolve, reject) => setTimeout(() => resolve('first resolved'), 1000));
const asyncTask2 = () => new Promise((resolve, reject) => setTimeout(() => resolve('second resolved'), 1000));
const asyncTask3 = () => new Promise((resolve, reject) => setTimeout(() => reject('third rejected'), 1000));
async function helper(func) {
let p = func().next().value
let output = await p
console.log(output)
}
helper(function* main() {
try {
const a = yield asyncTask1()
console.log(a);
const b = yield asyncTask2()
console.log(b);
const c = yield asyncTask3()
} catch (e) {
console.error('error happened', e);
}
})
Output: first resolved
Should be:
first resolved
second resolved
third rejected
You are calling the generator only once using .next() only once so the function would yield only once. Also, when you can func() you are creating a new generator every time. Your try catch block is in generator inside which is yield, so it won't catch the error since yield would not throw an error. Finally, third task will not be a success, it will throw an error as it is rejected.
I will do it as below -
const asyncTask1 = () => new Promise((resolve, reject) => setTimeout(() => resolve('first resolved'), 1000));
const asyncTask2 = () => new Promise((resolve, reject) => setTimeout(() => resolve('second resolved'), 1000));
const asyncTask3 = () => new Promise((resolve, reject) => setTimeout(() => reject('third rejected'), 1000));
async function execute() {
try {
const iterator = generator();
let p = iterator.next().value;
let output = await p;
console.log(output);
let q = iterator.next().value;
let output1 = await q;
console.log(output1);
let r = iterator.next().value;
let output2 = await r;
console.log(output3);
} catch (e) {
console.log('error happened', e);
}
}
const generator = function* generator() {
yield asyncTask1();
yield asyncTask2();
yield asyncTask3();
}
execute();
Referring to #Felix Kling's comment, a more elegant way to do this would be -
const asyncTask1 = () => new Promise((resolve, reject) => setTimeout(() => resolve('first resolved'), 1000));
const asyncTask2 = () => new Promise((resolve, reject) => setTimeout(() => resolve('second resolved'), 1000));
const asyncTask3 = () => new Promise((resolve, reject) => setTimeout(() => reject('third rejected'), 1000));
async function execute() {
const iterator = generator();
for await (const task of iterator) {
try {
let output = await task();
console.log(output);
} catch (e) {
console.log('error happened', e);
}
}
}
const generator = function* generator() {
yield*[asyncTask1, asyncTask2, asyncTask3];
}
execute();

How to set a time limit to a method in NodeJs?

I have a use case, where I am doing an external API call from my code,
The response of the external API is required by my code further on
I am bumping into a scenario, where the external API call at times takes far too long to return a response,
casing my code to break, being a serverless function
So I want to set a time limit to the external API call,
Where if I don't get any response from it within 3 secs, I wish the code to gracefully stop the further process
Following is a pseudo-code of what I am trying to do, but couldn't figure out the logic -
let test = async () => {
let externalCallResponse = '';
await setTimeout(function(){
//this call sometimes takes for ever to respond, but I want to limit just 3secs to it
externalCallResponse = await externalCall();
}, 3000);
if(externalCallResponse != ''){
return true;
}
else{
return false;
}
}
test();
Reference -
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SSM.html#getParameters-property
I'm using AWS SSM's getParameters method
You cannot await setTimeout as it doesn't returns a Promise.
You could implement a function that returns a Promise which is fulfilled after 3 seconds.
function timeout(seconds) {
return new Promise((resolve) => {
setTimeout(resolve, seconds * 1000)
});
}
You can await the above function in your code passing the number of seconds you want to wait for
let test = async () => {
let externalCallResponse = '';
setTimeout(async () => {
externalCallResponse = await externalCall();
}, 0);
await timeout(3); // wait for 3 seconds
if(externalCallResponse != '') return true;
else return false;
}
Following code snippet demonstrates the usage of timeout function written above. It mocks a api request that returns a response after 4 seconds.
function timeout(seconds) {
return new Promise(resolve => {
setTimeout(resolve, seconds * 1000);
});
}
function apiRequest() {
return new Promise(resolve => {
setTimeout(() => resolve('Hello World'), 4000);
});
}
let test = async () => {
let externalCallResponse = '';
setTimeout(async () => {
externalCallResponse = await apiRequest();
}, 0);
await timeout(3); // wait for 3 seconds
if (externalCallResponse != '') return true;
else return false;
};
test()
.then(res => console.log(res))
.catch(err => console.log(err.message));
you can use something like this, I created a function that return a promise then I used this promise.
let test = async () => {
return promiseTimeout()
}
const promiseTimeout = () => {
return new Promise(async (resolve, reject) => {
setTimeout(function () {
let externalCallResponse=""
externalCallResponse = await externalCall();
if (externalCallResponse != '') {
return resolve(true);
}
else {
return resolve(false);
}
}, 3000);
})
}
test().then(result=>{
console.log(result);
});
You could do something like this:
const timeout = async (func, millis) => {
return new Promise(async (resolve, reject) => {
setTimeout(() => reject(), millis);
resolve(await func());
});
}
timeout(() => doStuff(), 3000)
.then(() => console.log('worked'))
.catch(() => console.log('timed out'));
Tests:
const timeout = async (func, millis) => {
return new Promise(async (resolve, reject) => {
setTimeout(() => reject(), millis);
resolve(await func());
});
}
const doStuffShort = async () => { // Runs for 1 second
return new Promise((resolve) => setTimeout(() => resolve(), 1000));
}
const doStuffLong = async () => { // Runs for 5 seconds
return new Promise((resolve) => setTimeout(() => resolve(), 5000));
}
timeout(() => doStuffShort(), 3000)
.then(() => console.log('1 worked'))
.catch(() => console.log('1 timed out'));
timeout(() => doStuffLong(), 3000)
.then(() => console.log('2 worked'))
.catch(() => console.log('2 timed out'));

Categories

Resources