'setTimeout with Promises
I trying to solve a challenge with the following question:
Implements a function that takes a number as a parameter and after x milliseconds (between an interval of 1 to 100 ms. Use setTimeout and as floor and random functions from the Math library), without a console or with twice the received parameter. Then, call this function 5 times. Ex.:
Without performing any treatment, it is easy to notice that the order of the values shown on the console is random and does not accept the order of calling the functions. Therefore, to resolve this issue, treat or subscribe to setTimeout using callback, Promise and async / waitit.
That's the expected behavior:
let result;
result = double(5, 0); // returns 10
result = double(12, result); // returns 34
result = double(2, result); // returns 38
The goal is to treat the asynchronous behavior of setTimeout with promises, async functions or callbacks. That's was what i got until now and with no success:
function promisify(number, increase){
return new Promise(resolve => setTimeout(() => resolve(number * 2 + increase), 100))
}
async function double(number, increase) {
const value = await promisify(number, increase);
return value;
}
let result;
result = double(5, 0)
result = double(10, result)
result = double(20, result)
console.log(result)
- I want to return a promise with a set timeout that was a random calculate miliseconds until resolve the double of the number + the increase value if it exists.
- Even waiting for the promise to result in the async function, it continues to return a pending promise
- The result variables have to increase on each calc but they're receiving functions instead of the double result
Solution 1:[1]
You're actually almost there. All you need is to assign the value of the resolved promise to result
, instead of assigning the Promise object directly. This is done by using result = await double(<param1>, <param2>)
.
However, since JS does not yet support top-level await, you need to wrap your whole result
assignment logic in another async function, and then call it as such:
function promisify(number, increase){
return new Promise(resolve => setTimeout(() => resolve(number * 2 + increase), 100))
}
async function double(number, increase) {
const value = await promisify(number, increase);
return value;
}
async function run() {
let result;
result = await double(5, 0)
result = await double(10, result)
result = await double(20, result)
console.log(result)
}
run();
However, looking at your code, the double
function seems to only serve as a wrapper. Your code can be easily rewritten so that you perform the calculation immediately, but simply wait a little before resolving the promise:
// Simply forces the async operation to wait for a set duration
function wait(duration){
return new Promise(resolve => setTimeout(resolve, duration));
}
async function double(number, increase) {
await wait(100);
return (number * 2) + increase;
}
async function run() {
let result;
result = await double(5, 0)
result = await double(10, result)
result = await double(20, result)
console.log(result)
}
run();
In this way, you can then implement the question's desired randomized settimeout, if you want to, i.e.:
// Waits between [1, 1000] milliseconds
await wait(Math.random() * 1000);
Solution 2:[2]
You are close to the solution. The reason why this does not work is the following:
double is an async function. That means it does not return 10, 20, or any other number, but a Promise that resolves to this number as soon as possible (in this case, after the timeout).
That means you should wrap your code into another async function and use await to handle the promises:
async function doPrint() {
let result;
result = await double(5, 0)
result = await double(10, result)
result = await double(20, result)
console.log(result)
return result;
}
doPrint().then(function(result) { console.log('Returned result ' + result); });
Notice that the "then" method represents another way to deal with async functions: It is the usual method of any promise. Just remember that any async function returns a promise under the hood (even when not explicitly specified). The await syntax is just syntactic sugar around dealing with the then calls.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Terry |
Solution 2 |