Javascript understanding promises - javascript

I've been using async with NodeJS, but I'm trying to understand the basic of promises in JavaScript and I'm having issues with it.
I created the code below for testing.
function first() {
// Simulate a code delay
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
}, 500);
});
}
function second() {
console.log(2);
}
first().then(second());
It should print '1' first, but it is printing '2' in the console first. Why is it happening?
Thanks

Two things:
first().then(second()) invokes second() immediately and passes its return value as the argument to then. You want to pass in the function itself, not its return value:
first().then(second); // no parens on second
And you're never resolving the first promise:
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
resolve(); // <-- without this the promise is never resolved
}, 500);
}
);
With those issues addressed it works as you'd intended:
function first() {
// Simulate a code delay
return new Promise(function(resolve) {
setTimeout(function() {
console.log(1);
resolve(); // <-- without this the promise is never resolved
}, 500);
});
}
function second() {
console.log(2);
}
first().then(second);

There are a 2 problems in your code :
Your function first() returns a promise, but it isn't a promise in itself, so you cannot use the .then attribute on it.
You're not resolving anything in your 1st promise, you're just console.logging something, which is not something you can "wait" for.
What you're looking for is more something like this :
let first = new Promise((resolve) => {
setTimeout( function() {
console.log("1");
resolve(true); //you return your response, for example a boolean
}, 500)
})
function second(){
console.log("2");
}
first.then(response => {
//this is usually where you do something with the response
second();
});

Use Async Await
(as ray write) In new Promise() You must return resolve() or reject()
You can also use await:
function first() {
return new Promise(res => {
console.log(1);
return setTimeout(res, 500);
})
}
function second() {
console.log(2);
}
(async () => {
await first();
second();
})();

Related

How do I mock a delayed async function using setTimeout in Javascript [duplicate]

This is not a realworld problem, I'm just trying to understand how promises are created.
I need to understand how to make a promise for a function that returns nothing, like setTimeout.
Suppose I have:
function async(callback){
setTimeout(function(){
callback();
}, 5000);
}
async(function(){
console.log('async called back');
});
How do I create a promise that async can return after the setTimeout is ready to callback()?
I supposed wrapping it would take me somewhere:
function setTimeoutReturnPromise(){
function promise(){}
promise.prototype.then = function() {
console.log('timed out');
};
setTimeout(function(){
return ???
},2000);
return promise;
}
But I can't think beyond this.
Update (2017)
Here in 2017, Promises are built into JavaScript, they were added by the ES2015 spec (polyfills are available for outdated environments like IE8-IE11). The syntax they went with uses a callback you pass into the Promise constructor (the Promise executor) which receives the functions for resolving/rejecting the promise as arguments.
First, since async now has a meaning in JavaScript (even though it's only a keyword in certain contexts), I'm going to use later as the name of the function to avoid confusion.
Basic Delay
Using native promises (or a faithful polyfill) it would look like this:
function later(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
Note that that assumes a version of setTimeout that's compliant with the definition for browsers where setTimeout doesn't pass any arguments to the callback unless you give them after the interval (this may not be true in non-browser environments, and didn't used to be true on Firefox, but is now; it's true on Chrome and even back on IE8).
Basic Delay with Value
If you want your function to optionally pass a resolution value, on any vaguely-modern browser that allows you to give extra arguments to setTimeout after the delay and then passes those to the callback when called, you can do this (current Firefox and Chrome; IE11+, presumably Edge; not IE8 or IE9, no idea about IE10):
function later(delay, value) {
return new Promise(function(resolve) {
setTimeout(resolve, delay, value); // Note the order, `delay` before `value`
/* Or for outdated browsers that don't support doing that:
setTimeout(function() {
resolve(value);
}, delay);
Or alternately:
setTimeout(resolve.bind(null, value), delay);
*/
});
}
If you're using ES2015+ arrow functions, that can be more concise:
function later(delay, value) {
return new Promise(resolve => setTimeout(resolve, delay, value));
}
or even
const later = (delay, value) =>
new Promise(resolve => setTimeout(resolve, delay, value));
Cancellable Delay with Value
If you want to make it possible to cancel the timeout, you can't just return a promise from later, because promises can't be cancelled.
But we can easily return an object with a cancel method and an accessor for the promise, and reject the promise on cancel:
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
Live Example:
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
const l1 = later(100, "l1");
l1.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l1 cancelled"); });
const l2 = later(200, "l2");
l2.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l2 cancelled"); });
setTimeout(() => {
l2.cancel();
}, 150);
Original Answer from 2014
Usually you'll have a promise library (one you write yourself, or one of the several out there). That library will usually have an object that you can create and later "resolve," and that object will have a "promise" you can get from it.
Then later would tend to look something like this:
function later() {
var p = new PromiseThingy();
setTimeout(function() {
p.resolve();
}, 2000);
return p.promise(); // Note we're not returning `p` directly
}
In a comment on the question, I asked:
Are you trying to create your own promise library?
and you said
I wasn't but I guess now that's actually what I was trying to understand. That how a library would do it
To aid that understanding, here's a very very basic example, which isn't remotely Promises-A compliant: Live Copy
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Very basic promises</title>
</head>
<body>
<script>
(function() {
// ==== Very basic promise implementation, not remotely Promises-A compliant, just a very basic example
var PromiseThingy = (function() {
// Internal - trigger a callback
function triggerCallback(callback, promise) {
try {
callback(promise.resolvedValue);
}
catch (e) {
}
}
// The internal promise constructor, we don't share this
function Promise() {
this.callbacks = [];
}
// Register a 'then' callback
Promise.prototype.then = function(callback) {
var thispromise = this;
if (!this.resolved) {
// Not resolved yet, remember the callback
this.callbacks.push(callback);
}
else {
// Resolved; trigger callback right away, but always async
setTimeout(function() {
triggerCallback(callback, thispromise);
}, 0);
}
return this;
};
// Our public constructor for PromiseThingys
function PromiseThingy() {
this.p = new Promise();
}
// Resolve our underlying promise
PromiseThingy.prototype.resolve = function(value) {
var n;
if (!this.p.resolved) {
this.p.resolved = true;
this.p.resolvedValue = value;
for (n = 0; n < this.p.callbacks.length; ++n) {
triggerCallback(this.p.callbacks[n], this.p);
}
}
};
// Get our underlying promise
PromiseThingy.prototype.promise = function() {
return this.p;
};
// Export public
return PromiseThingy;
})();
// ==== Using it
function later() {
var p = new PromiseThingy();
setTimeout(function() {
p.resolve();
}, 2000);
return p.promise(); // Note we're not returning `p` directly
}
display("Start " + Date.now());
later().then(function() {
display("Done1 " + Date.now());
}).then(function() {
display("Done2 " + Date.now());
});
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
})();
</script>
</body>
</html>
const setTimeoutAsync = (cb, delay) =>
new Promise((resolve) => {
setTimeout(() => {
resolve(cb());
}, delay);
});
We can pass custom 'cb fxn' like this one 👆🏽
One-liner that wraps a promise around setTimeout
await new Promise(r => setTimeout(r, ms))
Example:
async someFunction() {
// Do something
// Wait 2 seconds
await new Promise(r => setTimeout(r, 2000))
// Do something else
}
Since node v15, you can use timers promise API
example from the doc:
import { setTimeout } from 'timers/promises'
const res = await setTimeout(100, 'result')
console.log(res) // Prints 'result'
It uses signals much like browser fetch to handle abort, check the doc for more :)
Implementation:
// Promisify setTimeout
const pause = (ms, cb, ...args) =>
new Promise((resolve, reject) => {
setTimeout(async () => {
try {
resolve(await cb?.(...args))
} catch (error) {
reject(error)
}
}, ms)
})
Tests:
// Test 1
pause(1000).then(() => console.log('called'))
// Test 2
pause(1000, (a, b, c) => [a, b, c], 1, 2, 3).then(value => console.log(value))
// Test 3
pause(1000, () => {
throw Error('foo')
}).catch(error => console.error(error))
This is not an answer to the original question. But, as an original question is not a real-world problem it should not be a problem. I tried to explain to a friend what are promises in JavaScript and the difference between promise and callback.
Code below serves as an explanation:
//very basic callback example using setTimeout
//function a is asynchronous function
//function b used as a callback
function a (callback){
setTimeout (function(){
console.log ('using callback:');
let mockResponseData = '{"data": "something for callback"}';
if (callback){
callback (mockResponseData);
}
}, 2000);
}
function b (dataJson) {
let dataObject = JSON.parse (dataJson);
console.log (dataObject.data);
}
a (b);
//rewriting above code using Promise
//function c is asynchronous function
function c () {
return new Promise(function (resolve, reject) {
setTimeout (function(){
console.log ('using promise:');
let mockResponseData = '{"data": "something for promise"}';
resolve(mockResponseData);
}, 2000);
});
}
c().then (b);
JsFiddle
The simplest way
(async function() {
console.log('1');
await SleepJs(3000);
console.log('2');
} )();
function SleepJs(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
If none of those solutions worked for you, please try this
const asyncTimeout = (ms) => {
// when you make a promise you have to resolve it or reject it
// if you are like me that didn't get promises at all read the docs
return new Promise((resolve, reject) => {
setTimeout(() => {
const users = [
{ id: 1, name: 'Pablo' },
{ id: 2, name: 'Pedro' }
]
resolve(users) // this returns users
}, ms)
})
}
(async () => {
const obj = await asyncTimeout(3000)
console.log(obj)
})()

replace callbacks with async and promises only first is triggered [duplicate]

This is not a realworld problem, I'm just trying to understand how promises are created.
I need to understand how to make a promise for a function that returns nothing, like setTimeout.
Suppose I have:
function async(callback){
setTimeout(function(){
callback();
}, 5000);
}
async(function(){
console.log('async called back');
});
How do I create a promise that async can return after the setTimeout is ready to callback()?
I supposed wrapping it would take me somewhere:
function setTimeoutReturnPromise(){
function promise(){}
promise.prototype.then = function() {
console.log('timed out');
};
setTimeout(function(){
return ???
},2000);
return promise;
}
But I can't think beyond this.
Update (2017)
Here in 2017, Promises are built into JavaScript, they were added by the ES2015 spec (polyfills are available for outdated environments like IE8-IE11). The syntax they went with uses a callback you pass into the Promise constructor (the Promise executor) which receives the functions for resolving/rejecting the promise as arguments.
First, since async now has a meaning in JavaScript (even though it's only a keyword in certain contexts), I'm going to use later as the name of the function to avoid confusion.
Basic Delay
Using native promises (or a faithful polyfill) it would look like this:
function later(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
Note that that assumes a version of setTimeout that's compliant with the definition for browsers where setTimeout doesn't pass any arguments to the callback unless you give them after the interval (this may not be true in non-browser environments, and didn't used to be true on Firefox, but is now; it's true on Chrome and even back on IE8).
Basic Delay with Value
If you want your function to optionally pass a resolution value, on any vaguely-modern browser that allows you to give extra arguments to setTimeout after the delay and then passes those to the callback when called, you can do this (current Firefox and Chrome; IE11+, presumably Edge; not IE8 or IE9, no idea about IE10):
function later(delay, value) {
return new Promise(function(resolve) {
setTimeout(resolve, delay, value); // Note the order, `delay` before `value`
/* Or for outdated browsers that don't support doing that:
setTimeout(function() {
resolve(value);
}, delay);
Or alternately:
setTimeout(resolve.bind(null, value), delay);
*/
});
}
If you're using ES2015+ arrow functions, that can be more concise:
function later(delay, value) {
return new Promise(resolve => setTimeout(resolve, delay, value));
}
or even
const later = (delay, value) =>
new Promise(resolve => setTimeout(resolve, delay, value));
Cancellable Delay with Value
If you want to make it possible to cancel the timeout, you can't just return a promise from later, because promises can't be cancelled.
But we can easily return an object with a cancel method and an accessor for the promise, and reject the promise on cancel:
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
Live Example:
const later = (delay, value) => {
let timer = 0;
let reject = null;
const promise = new Promise((resolve, _reject) => {
reject = _reject;
timer = setTimeout(resolve, delay, value);
});
return {
get promise() { return promise; },
cancel() {
if (timer) {
clearTimeout(timer);
timer = 0;
reject();
reject = null;
}
}
};
};
const l1 = later(100, "l1");
l1.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l1 cancelled"); });
const l2 = later(200, "l2");
l2.promise
.then(msg => { console.log(msg); })
.catch(() => { console.log("l2 cancelled"); });
setTimeout(() => {
l2.cancel();
}, 150);
Original Answer from 2014
Usually you'll have a promise library (one you write yourself, or one of the several out there). That library will usually have an object that you can create and later "resolve," and that object will have a "promise" you can get from it.
Then later would tend to look something like this:
function later() {
var p = new PromiseThingy();
setTimeout(function() {
p.resolve();
}, 2000);
return p.promise(); // Note we're not returning `p` directly
}
In a comment on the question, I asked:
Are you trying to create your own promise library?
and you said
I wasn't but I guess now that's actually what I was trying to understand. That how a library would do it
To aid that understanding, here's a very very basic example, which isn't remotely Promises-A compliant: Live Copy
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Very basic promises</title>
</head>
<body>
<script>
(function() {
// ==== Very basic promise implementation, not remotely Promises-A compliant, just a very basic example
var PromiseThingy = (function() {
// Internal - trigger a callback
function triggerCallback(callback, promise) {
try {
callback(promise.resolvedValue);
}
catch (e) {
}
}
// The internal promise constructor, we don't share this
function Promise() {
this.callbacks = [];
}
// Register a 'then' callback
Promise.prototype.then = function(callback) {
var thispromise = this;
if (!this.resolved) {
// Not resolved yet, remember the callback
this.callbacks.push(callback);
}
else {
// Resolved; trigger callback right away, but always async
setTimeout(function() {
triggerCallback(callback, thispromise);
}, 0);
}
return this;
};
// Our public constructor for PromiseThingys
function PromiseThingy() {
this.p = new Promise();
}
// Resolve our underlying promise
PromiseThingy.prototype.resolve = function(value) {
var n;
if (!this.p.resolved) {
this.p.resolved = true;
this.p.resolvedValue = value;
for (n = 0; n < this.p.callbacks.length; ++n) {
triggerCallback(this.p.callbacks[n], this.p);
}
}
};
// Get our underlying promise
PromiseThingy.prototype.promise = function() {
return this.p;
};
// Export public
return PromiseThingy;
})();
// ==== Using it
function later() {
var p = new PromiseThingy();
setTimeout(function() {
p.resolve();
}, 2000);
return p.promise(); // Note we're not returning `p` directly
}
display("Start " + Date.now());
later().then(function() {
display("Done1 " + Date.now());
}).then(function() {
display("Done2 " + Date.now());
});
function display(msg) {
var p = document.createElement('p');
p.innerHTML = String(msg);
document.body.appendChild(p);
}
})();
</script>
</body>
</html>
const setTimeoutAsync = (cb, delay) =>
new Promise((resolve) => {
setTimeout(() => {
resolve(cb());
}, delay);
});
We can pass custom 'cb fxn' like this one 👆🏽
One-liner that wraps a promise around setTimeout
await new Promise(r => setTimeout(r, ms))
Example:
async someFunction() {
// Do something
// Wait 2 seconds
await new Promise(r => setTimeout(r, 2000))
// Do something else
}
Since node v15, you can use timers promise API
example from the doc:
import { setTimeout } from 'timers/promises'
const res = await setTimeout(100, 'result')
console.log(res) // Prints 'result'
It uses signals much like browser fetch to handle abort, check the doc for more :)
Implementation:
// Promisify setTimeout
const pause = (ms, cb, ...args) =>
new Promise((resolve, reject) => {
setTimeout(async () => {
try {
resolve(await cb?.(...args))
} catch (error) {
reject(error)
}
}, ms)
})
Tests:
// Test 1
pause(1000).then(() => console.log('called'))
// Test 2
pause(1000, (a, b, c) => [a, b, c], 1, 2, 3).then(value => console.log(value))
// Test 3
pause(1000, () => {
throw Error('foo')
}).catch(error => console.error(error))
This is not an answer to the original question. But, as an original question is not a real-world problem it should not be a problem. I tried to explain to a friend what are promises in JavaScript and the difference between promise and callback.
Code below serves as an explanation:
//very basic callback example using setTimeout
//function a is asynchronous function
//function b used as a callback
function a (callback){
setTimeout (function(){
console.log ('using callback:');
let mockResponseData = '{"data": "something for callback"}';
if (callback){
callback (mockResponseData);
}
}, 2000);
}
function b (dataJson) {
let dataObject = JSON.parse (dataJson);
console.log (dataObject.data);
}
a (b);
//rewriting above code using Promise
//function c is asynchronous function
function c () {
return new Promise(function (resolve, reject) {
setTimeout (function(){
console.log ('using promise:');
let mockResponseData = '{"data": "something for promise"}';
resolve(mockResponseData);
}, 2000);
});
}
c().then (b);
JsFiddle
The simplest way
(async function() {
console.log('1');
await SleepJs(3000);
console.log('2');
} )();
function SleepJs(delay) {
return new Promise(function(resolve) {
setTimeout(resolve, delay);
});
}
If none of those solutions worked for you, please try this
const asyncTimeout = (ms) => {
// when you make a promise you have to resolve it or reject it
// if you are like me that didn't get promises at all read the docs
return new Promise((resolve, reject) => {
setTimeout(() => {
const users = [
{ id: 1, name: 'Pablo' },
{ id: 2, name: 'Pedro' }
]
resolve(users) // this returns users
}, ms)
})
}
(async () => {
const obj = await asyncTimeout(3000)
console.log(obj)
})()

Javascript Promise chaining not working as expected

I am trying to return a promise inside a promise but cannot get it to work
Here is my code
async function main() {
return new Promise((resolve, reject) => {
p = new Promise((resolve, reject) => {
f2(async() => {
resolve();
});
});
array = [];
array.push(p);
Promise.all(array).then(resolve(1));
});
}
setTimeout(async() => {
console.log(await main());
}, 0);
function f2(callback) {
console.log("h called");
setTimeout(() => {
callback();
}, 4000);
}
I expect that he array will be resolved after the timeout in f2() but it is resolving instantly.
Any help will be appreciated
The resolve function is being called right away, try something like this:
Promise.all(array).then(() => {
resolve(1);
});
Edit: I wanted to add that what is passed to the then() callback of a promise is a statement, using resolve(1) is a call to execute that code, but by wrapping that function call in an anonymous function declaration, the entire function declaration is passed, and then called when needed.

Unable to resolving the promise inside of a function

Here is a piece of my original code, Why I can't resolve the instruct function this way?
Actually I used to resolve the promises like this and the same codes for other functions worked before.
I'm not able to find the reason and the solution without a hand.
var instructResolve;
async function instruct(location, category){
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
instructResolve();
break;
}
return new Promise((resolve) => {
instructResolve = resolve;
});
};
function audioPlay(source){
console.log('await audioPlay..')
return new Promise((resolve) => {
setTimeout(function(){
console.log('audioPlay resolved..')
resolve();
}, 5000)
});
}
recognize();
async function recognize(){
await instruct('User_Was_Silent');
//After resolving instruct do stuff like logging some success message on the console
console.log('Final log success!')
}
At the recognize function I'm waiting for the instruct function to resolve and then we do stuff like logging some success message on the console, but since recognize for some reason doesn't resolve we can not see the console.log('Final log success!')
UPDATE:
I have a similar code that works just fine without any issues, I have implemented the promises and resolves just like the code above but it works!
var updateGuiderResolve;
function updateGuider(state, guide, lower){
console.log('updateGuider...')
switch(state) {
case 'default':
stateReveal("default");
break;
}
return new Promise((resolve) => {
updateGuiderResolve = resolve;
});
}
function stateReveal(state){
console.log('stateReveal...')
setTimeout(function(){
speak();
}, 5000);
}
function speak(){
console.log('speak...')
setTimeout(function(){
console.log('updateGuiderResolve...')
updateGuiderResolve()
}, 5000);
}
async function tutor(){
await updateGuider('default');
console.log('final...')
}
tutor()
I can see 2 problems in the code base.
One is
instructResolve(); // It's not function, I think as it's only declared at first.
Second one is
await instruct('User_Was_Silent'); // This does not need to add await as it's already async function. Simply call instruct('User_Was_Silent'); and missing second param in this function.
var instructResolve;
async function instruct(location, category=null){
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
break;
}
};
function audioPlay(source){
console.log('await audioPlay..')
return new Promise((resolve) => {
setTimeout(function(){
console.log('audioPlay resolved..')
resolve();
}, 5000)
});
}
async function recognize(){
await instruct('User_Was_Silent');
//After resolving instruct do stuff like logging some success message on the console
console.log('Final log success!')
}
recognize();
Try calling instructResolve inside Promise like that:
var instructResolve;
async function instruct(location, category){
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
break;
}
return new Promise((resolve) => {
instructResolve = resolve;
instructResolve();
});
}
There is a solution like this one but I want to know why the question's code doesn't work?
var instructResolve;
async function instruct(location, category){
return new Promise(async (resolve) => {
switch(location) {
case 'User_Was_Silent':
console.log('Start!')
await audioPlay();
console.log('After audioPlay await is done, then resolve instruct!')
resolve();
break;
}
});
};
function audioPlay(source){
console.log('await audioPlay..')
return new Promise((resolve) => {
setTimeout(function(){
console.log('audioPlay resolved..')
resolve();
}, 5000)
});
}
async function recognize(){
await instruct('User_Was_Silent');
//After resolving instruct do stuff like logging some success message on the console
console.log('Final log success!')
}
recognize();

Async/Await code not being executes after await

I have been going over async/await. I trying few simple examples but unable to understand flow of async and await . In below code
function wait(ms) {
return new Promise(r => setTimeout(function() {
console.log('Hello');
}, ms));
}
async function GetUser() {
await wait(5000);
console.log('world');
}
GetUser();
Why is the message "world" not logged? Only "Hello" prints.
You should call the resolver.
function wait(ms) {
return new Promise(r => setTimeout(function(){console.log('Hello'); r();},
// ^^^ this
ms));
}
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
You need to resolve it. So call r()
function wait(ms) {
return new Promise(r => setTimeout(function() {
console.log('Hello');
r()
}, ms));
}
async function GetUser() {
await wait(3000)
console.log('world');
}
GetUser()
Here wait() method returns a Promise, the function of await keyword is to stop code execution until the returned Promise by wait() is resolved.
So the code snippet in question, without using async/await will be as below. Note that the resolve function is not yet invoked here. Hence, once the snippet is executed only Hello will get printed in the console.
// First code snippet
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
}, ms));
}
function GetUser() {
return wait(1000)
.then(() => {
console.log("World")
})
.catch((err) => {
console.log(err);
})
}
GetUser()
Code snippet when r() is invoked. Here, once the snippet is executed Hello and World both are printed in the console.
// Second code snippet
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
r();
}, ms));
}
function GetUser() {
return wait(1000)
.then(() => {
console.log("World")
})
.catch((err) => {
console.log(err);
})
}
GetUser()
The reason why the second code snippet works, has to do with how Promise is implemented in JS.
Handler function/functions attached to a promise with the help of .then() are invoked only when the promise is resolved.
Code snippet when resolve method is not invoked inside the executor function i.e, when the Promise is not resolved. Here, only code inside setTimeout is invoked and not the handlers.
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
}, ms));
}
const promiseReturnedByWaitMethod = wait(2000);
// Multiple handlers can be added to a promise reference, which are executed when the asynchronous operation is completed.
// adding first handler
promiseReturnedByWaitMethod.then(() => {
console.log("First handler!!")
});
// adding second handler
promiseReturnedByWaitMethod.then(() => {
console.log("Second handler!!")
});
Code snippet when resolve method is invoked inside the executor function i.e, when the Promise is resolved.
function wait(ms) {
return new Promise(r => setTimeout(function () {
console.log('Hello');
r();
}, ms));
}
const promiseReturnedByWaitMethod = wait(2000);
// Multiple handlers can be added to a promise reference, which are executed when the asynchronous operation is completed.
// adding first handler
promiseReturnedByWaitMethod.then(() => {
console.log("First handler!!")
});
// adding second handler
promiseReturnedByWaitMethod.then(() => {
console.log("Second handler!!")
});

Categories

Resources