Promises in a const function in nodejs - javascript

This is my function
const f = (value,err) => {
if(!value === Number){
throw err;
}
return (value);
}
Using promises I want to return an object of parameter value and after some wait it will return parameter in number. Is that possible?

A promise doesn't do anything in and of itself, and it doesn't make anything asynchronous in and of itself (other than that promise reactions are always asynchronous¹). A promise is just a standardized way to report the completion of something that's (potentially) asynchronous. So the literal answer to your question is: No, you can't use a promise to do that, not on its own. You'd have to combine it with something like setTimeout or similar.
Also note that if (!value === Number) is always false. It's evaluated like this: !value, negating the value of value, and then x === Number, which will always be false because there is no value that, when negated, turns into the Number function.
But for instance, if you wanted to check whether something is a number but not respond for 100ms:
const f = (value, err) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (typeof value !== "number") {
reject(err);
} else {
resolve(value);
}
}, 100);
});
};
Other than the promise, the two significant changes there are:
Using setTimeout to introduce asynchronousness, and
Changing the if condition to something that won't always be false (I may or may not have guessed correctly what you wanted there :-) )
¹ A promise reaction is a call to a then, catch, or finally callback registered on the promise. Here's an example of what I mean by "promise reactions are asynchronous:"
console.log("Before creating the promise");
new Promise(resolve => {
console.log("Inside the promise executor function");
resolve(42);
})
.then(value => {
console.log(`Promise reaction ran, value = ${value}`);
});
console.log("After creating the promise");
That code has this output:
Before creating the promise
Inside the promise executor function
After creating the promise
Promise reaction ran, value = 42
Notice that everything was synchronous except the call to the then callback (the promise reaction), which per specification is always done asynchronously, even if (as in this case) the promise is already settled when the reaction is added to it.

Related

How JavaScript promises work behind the scenes

I'm so much confused about what happens behind the scenes when promise is produced and consume. Please clarify my points and sorry for my weak English.
blank object is created with new keyword Promise constructor is
called and new keyword set the this of Promise constructor points to
the blank object this = blankobject.
Promise constructor receives callback (executor function) in argument
and calls the executor function.
executor function receives two callbacks (resolve,reject) as arguments
setTimeout gets called in the executor function and setTimeOut is
async code
async code goes to background and then Promise constructor returns
Promise object formerly blank object and Promise object reference
saved to myPromise.
a variable is created
What happens next ? When then method is called the code of then method goes to background? I imagine it goes to background and a variable is console.log // 10
After main code execution finishes, async code start setTimeout callback begins to execute and after execution finishes promise is fulfilled and resolved function returns value. How is this value stored in promise object and what happens in then method ?
let myPromise = new Promise (
(resolve, reject) => {
setTimeout(() => {
console.log(getIDs)
resolve(10);
}, 1500);
}
)
let a = 10
myPromise.then(val => {
console.log(val);
})
console.log(a)
The following is a simplified implementation of the built-in Promise class. catch and finally have not been implemented.
The function supplied to the Promise constructor is called the executor function, and is invoked immediately and synchronously.
Every promise has a method .then, enabling the chaining of promises.
Functions supplied to .then are always invoked asynchronously on a microtask (note use of queueMicrotask below).
Every time .then is called, a new promise is created and returned.
.then can be called more than once on the same promise, creating a multicast of the result of the promise, and a branching of the promise chain.
A promise can be in one of three states: pending, fulfilled, or rejected. State transitions are unidirectional: you cannot move from fulfilled or rejected, back to pending.
If a promise is resolved with another promise, then the two promise chains are joined and the outer promise takes on the status of the inner promise (which could be pending), until the inner promise resolves.
function Promise(executor) {
if (!executor) throw "Promise executor undefined"
let status = "pending", value, thenQ = []
const then = onFulfilled => {
let resolver
// This ensures control does not move to later promises
// until prior promises have been resolved.
const nextPromise = new Promise(resolve => (resolver = resolve))
// More than one "then" can be registered with each promise.
thenQ.push((...args) => resolver(onFulfilled(...args)))
return nextPromise
}
// We check if the result is a "thenable"; if so, we treat
// it as an inner promise, otherwise we simply fulfil with
// the result.
const resolve = result => result?.then ? result.then(fulfil) : fulfil(result)
// When a promise has been fulfilled, its "thens" can be run.
const fulfil = result => (status = "fulfilled", value = result, executeThens(value))
// "Thens" are run asynchronously, on a microtask.
const executeThens = value => queueMicrotask(() => thenQ.forEach(el => el(value)))
// The executor is run synchronously.
executor(resolve)
return {
then,
get status() { return status },
get value() { return value }
}
}
// Chaining
new Promise(resolve => {
console.log('Waiting for step 1...')
setTimeout(() => resolve("One, two..."), 1500)
})
.then(result => new Promise(resolve => {
console.log('Waiting for step 2...')
setTimeout(() => resolve(`${result}three, four`), 1500)
}))
.then(result => console.log(`Chaining result: ${result}.`))
// Branching
const p = new Promise(resolve => {
console.log('Waiting for step a...')
setTimeout(() => resolve("Alpha, Bravo..."), 1500)
})
p.then(result => new Promise(resolve => {
console.log('Waiting for step b1...')
setTimeout(() => resolve(`${result}Charlie, Delta`), 1500)
})).then(console.log)
p.then(result => {
console.log('Waiting for step b2...')
return `${result}Echo, Foxtrot`
}).then(console.log)
See also.
I'll go through your code in the order of execution.
At all times the value of this is whatever it was at the beginning. That's because you're only using arrow functions. But that's not relevant since you're not referencing this.
Main Code
let myPromise = new Promise(executor); creates a pending promise object. While creating the promise, the executor function will be executed.
setTimeout(callback, 1500); puts the callback function on some internal timer queue. The javascript engine promises to do its best to execute callback after (at least) 1500ms.
let a = 10; sets the variable a to 10.
myPromise.then(onFulfilled); creates another pending promise. It is linked to myPromise so that onFulfilled will be scheduled asynchronously when myPromise is fulfilled.
console.log(a); prints the value of a which is 10.
For the next 1500ms nothing happens. Then callback gets executed.
callback of setTimeout
console.log(getIDs); prints getIDs. From the name you can guess it's a function. So something like [Function: getIDs] will be printed.
resolve(10); fulfills myPromise and sets its result to 10. Since myPromised is now fulfilled, onFulfilled of anotherPromise gets scheduled asynchronously.
Now we have to wait for the call stack to process. After that, onFulfilled will be called.
onFulfilled of myPromise.then
console.log(val); prints the content of val. That is, the result of myPromise.

Difference between Promise.resolve() and Promise(resolve => resolve()) [duplicate]

I'm using bluebird and I see two ways to resolve synchronous functions into a Promise, but I don't get the differences between both ways. It looks like the stacktrace is a little bit different, so they aren't just an alias, right?
So what is the preferred way?
Way A
function someFunction(someObject) {
return new Promise(function(resolve) {
someObject.resolved = true;
resolve(someObject);
});
}
Way B
function someFunction(someObject) {
someObject.resolved = true;
return Promise.resolve(someObject);
}
Contrary to both answers in the comments - there is a difference.
While
Promise.resolve(x);
is basically the same as
new Promise(function(r){ r(x); });
there is a subtlety.
Promise returning functions should generally have the guarantee that they should not throw synchronously since they might throw asynchronously. In order to prevent unexpected results and race conditions - throws are usually converted to returned rejections.
With this in mind - when the spec was created the promise constructor is throw safe.
What if someObject is undefined?
Way A returns a rejected promise.
Way B throws synchronously.
Bluebird saw this, and Petka added Promise.method to address this issue so you can keep using return values. So the correct and easiest way to write this in Bluebird is actually neither - it is:
var someFunction = Promise.method(function someFunction(someObject){
someObject.resolved = true;
return someObject;
});
Promise.method will convert throws to rejects and returns to resolves for you. It is the most throw safe way to do this and it assimilatesthenables through return values so it'd work even if someObject is in fact a promise itself.
In general, Promise.resolve is used for casting objects and foreign promises (thenables) to promises. That's its use case.
There is another difference not mentioned by the above answers or comments:
If someObject is a Promise, new Promise(resolve) would cost two additional tick.
Compare two following code snippet:
const p = new Promise(resovle => setTimeout(resovle));
new Promise(resolve => resolve(p)).then(() => {
console.log("tick 3");
});
p.then(() => {
console.log("tick 1");
}).then(() => {
console.log("tick 2");
});
const p = new Promise(resolve => setTimeout(resolve));
Promise.resolve(p).then(() => {
console.log("tick 3");
});
p.then(() => {
console.log("tick 1");
}).then(() => {
console.log("tick 2");
});
The second snippet would print 'tick 3' firstly. Why?
If the value is a promise, Promise.resolve(value) would return value exactly. Promise.resolve(value) === value would be true. see MDN
But new Promise(resolve => resolve(value)) would return a new promise which has locked in to follow the value promise. It needs an extra one tick to make the 'locking-in'.
// something like:
addToMicroTaskQueue(() => {
p.then(() => {
/* resolve newly promise */
})
// all subsequent .then on newly promise go on from here
.then(() => {
console.log("tick 3");
});
});
The tick 1 .then call would run first.
References:
http://exploringjs.com/es6/ch_promises.html#sec_demo-promise

How does JavaScript know to wait for the result of an inner promise?

I am trying to wrap my head around the incredibly confusing topics of Promises in Javascript.
One of the doubts that I encountered is that what happens when a then() callback actually returns a promise.
Look at the code below taken from javascript.info
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
}).then(function(result) {
alert(result); // 1
//Actually resolves before calling the next then()
return new Promise((resolve, reject) => { // (*)
setTimeout(() => resolve(result * 2), 1000);
});
}).then(function(result) { // (**)
alert(result); // 2
return new Promise((resolve, reject) => {
setTimeout(() => resolve(result * 2), 1000);
});
}).then(function(result) {
alert(result); // 4
});
Anyone of the inner promises is actually fulfilled before moving on to the next then statement.
Why is that? How does Javascript know when the returned value is a promise itself?
Is there really a check within the JS interpreter for this? Like something like this-:
if(ret_value instanceof Promise) {
wait_for_promise(ret_value);
}
This does not really make sense intuitively. You would think that the return value will be kept as is, ie the next then() in the chain would receive a promise and not the result of the promise.
I come from a Java background which is probably why this loose typing is irritating me.
The actual check that is performed is against thenables, not only against Promises.
If the returned value of a Promise resolver has a .then method, this method will be called, and the next resolver/rejecter will receive this method's value as argument:
const thenable = { // simple object, not an instance of Promise per se
then: (res, rej) => setTimeout(() => res('from thenable'), 1000)
};
Promise.resolve(1)
.then(v => thenable)
.then(console.log)
Promise.resolve()
.then(() => {
return new Promise(res => setTimeout(() => res(1),1000))
})
.then(v => {
console.log(v); //1
});
Take a look at the second then in the example above: I passed in a callback to log the value. Because a Promise was returned in the first then, JavaScript will not execute the callback in the second then until the Promise returned from the first then is resolved.
If, instead, in the first then I passed back a value (below), instead of a Promise, JavaScript would execute the callback I passed into the second then immediately.
Promise.resolve()
.then(() => {
return 1
})
.then(v => {
console.log(v); //1
});
Why is that? How does Javascript know when the returned value is a promise itself?
Maybe this can illustrate an answer to your question:
let x = Promise.resolve();
console.log(x instanceof Promise); //true - JavaScript "knows" that x is a promise
let y = 1;
console.log(y instanceof Promise); //false
In my opinion #kaiido s answer is the one You're searching for.
Simplified, an implementation of a promise internally could do a check like this one:
if( typeof(retValue.then)==="function" ) {
retValue.then( yourCallback );
}else{
yourCallback( retValue );
}
Wrote this on mobile phone. Please excuse my formatting.

Which way of resolving a value from a promise is correct?

I'm still new to all this asynchronous stuff in JavaScript, and I ran into a bit of a confusing situation when working with some promises. Here's my current code:
exists(filename, targetDir){
const filepath = path.join(targetDir || this.getTargetDir(), filename);
// plug in any one method from below
}
When I look into other people's code, I see them resolving values like this (plug into the code above):
// method 1
return request(this.getUrl(filepath))
.then(res => {
return Promise.resolve(res.statusCode === 200);
})
.catch(() => {
return Promise.resolve(false);
});
// method 2
return request(this.getUrl(filepath))
.then(res => {
Promise.resolve(res.statusCode === 200);
})
.catch(() => {
Promise.resolve(false);
});
// method 3
return request(this.getUrl(filepath))
.then(res => {
return res.statusCode === 200;
})
.catch(() => {
return false;
});
// method 4
return new Promise((resolve, reject) => {
request(this.getUrl(filepath))
.then(res => {
resolve(res.statusCode === 200);
}
.catch(() => {
resolve(false);
};
});
Which ones are correct in this case? Which ones are incorrect? Does it depend on the scenario? Which one of these are recommended? A good explanation would be appreciated, thanks!
Clarification: exists is a class method which returns a Promise which resolves to a boolean, where true means that the URL exists, and false means that it doesn't exist.
Clarification #2: exists should resolve to false if an error occurs.
Method 1 is correct but unnecessarily complicated.
Method 2 is plain wrong.
You create new Promises but they ain't populated anywhere so they get disposed when the function ends.
It is equivalent to:
return request(this.getUrl(filepath)).catch(err => undefined);
Method 3 is the best way to do it.
Method 4 would also resolve to the corect value, but it is an antipattern.
What is the explicit promise construction antipattern and how do I avoid it?
Method 3 is the best.
The next .then() recieves what the current .then() returns. If this return value happens to be a promise, the next .then() is executed after the promise has resolved.
Using method 3, you will be able to append other .then()s to the current chain:
exists('test.txt', '/')
.then(doesExist => console.log(doesExist ? 'The file exists.' : 'The file doesn\'t exist.'));
This is possible with method 1 and method 4 as well, but method 1 unnecessarily wraps the value in a promise which will resolve immediately.
Method 4 unnecessarily wraps the whole request in a promise. This is called the explicit-construction anti-pattern.
Method 2 does not allow promise chaining. You can't use the value that's wrapped in the Promise.resolve, because both the .then() and the .catch() implicitly return undefined.

Promise.resolve vs new Promise(resolve)

I'm using bluebird and I see two ways to resolve synchronous functions into a Promise, but I don't get the differences between both ways. It looks like the stacktrace is a little bit different, so they aren't just an alias, right?
So what is the preferred way?
Way A
function someFunction(someObject) {
return new Promise(function(resolve) {
someObject.resolved = true;
resolve(someObject);
});
}
Way B
function someFunction(someObject) {
someObject.resolved = true;
return Promise.resolve(someObject);
}
Contrary to both answers in the comments - there is a difference.
While
Promise.resolve(x);
is basically the same as
new Promise(function(r){ r(x); });
there is a subtlety.
Promise returning functions should generally have the guarantee that they should not throw synchronously since they might throw asynchronously. In order to prevent unexpected results and race conditions - throws are usually converted to returned rejections.
With this in mind - when the spec was created the promise constructor is throw safe.
What if someObject is undefined?
Way A returns a rejected promise.
Way B throws synchronously.
Bluebird saw this, and Petka added Promise.method to address this issue so you can keep using return values. So the correct and easiest way to write this in Bluebird is actually neither - it is:
var someFunction = Promise.method(function someFunction(someObject){
someObject.resolved = true;
return someObject;
});
Promise.method will convert throws to rejects and returns to resolves for you. It is the most throw safe way to do this and it assimilatesthenables through return values so it'd work even if someObject is in fact a promise itself.
In general, Promise.resolve is used for casting objects and foreign promises (thenables) to promises. That's its use case.
There is another difference not mentioned by the above answers or comments:
If someObject is a Promise, new Promise(resolve) would cost two additional tick.
Compare two following code snippet:
const p = new Promise(resovle => setTimeout(resovle));
new Promise(resolve => resolve(p)).then(() => {
console.log("tick 3");
});
p.then(() => {
console.log("tick 1");
}).then(() => {
console.log("tick 2");
});
const p = new Promise(resolve => setTimeout(resolve));
Promise.resolve(p).then(() => {
console.log("tick 3");
});
p.then(() => {
console.log("tick 1");
}).then(() => {
console.log("tick 2");
});
The second snippet would print 'tick 3' firstly. Why?
If the value is a promise, Promise.resolve(value) would return value exactly. Promise.resolve(value) === value would be true. see MDN
But new Promise(resolve => resolve(value)) would return a new promise which has locked in to follow the value promise. It needs an extra one tick to make the 'locking-in'.
// something like:
addToMicroTaskQueue(() => {
p.then(() => {
/* resolve newly promise */
})
// all subsequent .then on newly promise go on from here
.then(() => {
console.log("tick 3");
});
});
The tick 1 .then call would run first.
References:
http://exploringjs.com/es6/ch_promises.html#sec_demo-promise

Categories

Resources