Promise behavior and printing order - javascript

I'm a bit new to JavaScript and i can't figure out why the printing order of the following code is Noam and then Amit and only them.
can someone clarify it?
function rc(){
console.log('Assaf');
}
function thenCall(){
console.log('Amit');
}
function myPromise(){
return Promise.resolve(function(){
console.log('Yarden');
rc();
});
}
myPromise().then(function(){thenCall()});
console.log('Noam');

Promise.resolve takes a result which is passed to the then. It does not call the function. Notice the callback to .then.
function rc(){
console.log('Assaf');
}
function thenCall(){
console.log('Amit');
}
function myPromise(){
return Promise.resolve(function(){
console.log('Yarden');
rc();
});
}
myPromise().then(function(fn){
console.log(fn); // notice
thenCall()
});
console.log('Noam');

The function inside Promise.resolve should be executed as it will wait for a result to return:
function rc(){
console.log('Assaf');
}
function thenCall(){
console.log('Amit');
}
function myPromise(){
return Promise.resolve(function(){
console.log('Yarden');
rc();
}());
}
myPromise().then(function(){thenCall()});
console.log('Noam');

Let's divide the question by the people you're trying to log
Noam
Noam is printed first, because there is no async process in the code. You do use a Promise but it instantly executes the resolve method.
Amit
When Promise.resolve gets invoked, the function in the .then method will be executed. Therefore Amit gets printed in the console correctly.
Yarden and Assaf
Promise.resolve immediately resolves a new Promise and calls therefore the .then method immediately. The argument given to Promise.resolve is the value that will be passed as an argument to the .then method.
To create an actual Promise that either resolves or rejects based on some logic, this should get you started:
var a = true;
function myPromise() {
return new Promise(function (resolve, reject) {
console.log('first');
if (a) {
return setTimeout(function () {
resolve('value_to_pass_to_then');
}, 1000);
}
return reject('value_to_pass_to_catch');
});
}
myPromise()
.then(function (val) { console.log('second'); })
.catch(function (val) {})

The Yarden function is what the promise returned by myPromise() resolves to. But you aren't doing anything with the resolve value:
myPromise().then(function(/* resolve value would go here */){thenCall()});
The value a promise resolves to is the first argument of the function passed to .then. But you don't have an argument there. If you wanted to run that function, you would have to use it as an argument and then call it explicitly (which would in turn call the function that prints Assaf):
function rc() {
console.log('Assaf');
}
function thenCall() {
console.log('Amit');
}
function myPromise() {
return Promise.resolve(function() {
console.log('Yarden');
rc();
});
}
myPromise().then(function(yardenFn) {
thenCall();
yardenFn();
});
console.log('Noam');

Related

How to return a Promise from a function passed to Deferred.pipe()

The following chain is to be executed sequentially
$.when()
.pipe(functionA)
.pipe(functionB)
.fail(functionC);
where functionA returns a Promise.
function functionA() {
return networkCall().then(sideEffectsForSuccess).catch(sideEffectsForFailure);
}
function networkCall() {
return new Promise(function (resolve, reject) {
return $.ajax(...);
});
}
However, this doesn't seem to work, since functionB gets immediately executed without waiting for the Promise returned from functionA to resolve (or fail). The chain works correctly if functionA is changed to
function functionA() {
return $.ajax(...).pipe(sideEffectsForSuccess, sideEffectsForFailure);
}
Unfortunately, I have to use networkCall. Any ideas how to make this work?
Can you return the promise
function functionA() {
let callPromise = networkCall();
callPromise.then(sideEffectsForSuccess).catch(sideEffectsForFailure);
return callPromise;
}

How to grab value of promise and fire function

I know this is a common question asked, but I'm having a bit of an issue, trying to fire a function, ONLY when a promise has been returned. I also want to grab the value returned of the promise.
So I want to access an angular service, which seems to make an API call.
Wait for the promise to resolve.
Then store the promise returned as a value.
And then fire the function hello()
It seems when I fire run my code below, validPassengerId and hello()console.logs, before the promise has resolved.
How do I rewrite this code, to:
Wait for promise to resolve.
Then grab the value of the promise resolved - validPassengerId. (And then console.log it).
And then fire the function hello()?
function hello() {
console.log("hello");
};
const promise = new Promise((resolve, reject) => {
let validPassengerId = _funnelBasketLuggageService.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag);
resolve(validPassengerId);
});
promise.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});
Assuming FindValidPassengerIdForBag returns a promise, you do not need to wrap it in another promise. You would use it like this:
_funnelBasketLuggageService
.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag)
.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});
If validPassengerId is null with this code, then that must be what FindValidPassengerIdForBag is resolving its promise to. If you weren't expecting that, check the code of FindValidPassengerIdForBag or check that you're passing in valid parameters.
If in fact _funnelBasketLuggageService.FindValidPassengerIdForBag returns a promise, you solve this without creating your own Promise:
function hello() {
console.log("hello");
};
const promise = _funnelBasketLuggageService.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag);
promise.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});
Explanation What you did was actually wrapping the Promise returned by FindValidPassengerIdForBag in another Promise that returns immediately.
If you absolutely have to wrap it in your own Promise, e.g. because you need to do some preprocessing, use .then instead of the return value of the function:
function hello() {
console.log("hello");
};
const promise = new Promise((resolve, reject) => {_funnelBasketLuggageService.FindValidPassengerIdForBag(PassengerIds, bagsAssignedToPassengers, bag).then(id=>resolve(id));
});
promise.then(validPassengerId => {
console.log("validPassengerId", validPassengerId);
hello();
});

Wait for return statement from "then" of angular $q.all

I have a function and inside the function, I have a $q.all call as follows
function test()
{
$q.all(promises).then(function(response)
{
return response;
});
}
But my function doesn't return anything as it is not waiting for the response. Also, what should I do if I have to return from the then part of a $q.all inside a $q.all
You return the promise itself and chain .then handlers from there.
function test() {
return $q.all(promises);
}
test().then(function (response) {
// do stuff with response
});
Returning a promise from a .then handler adds it to the outer promise chain, so you can chain promises together like so:
function test() {
$q.all(promises).then(function (response) {
return $q.all(morePromises);
});
}
test().then(function (morePromisesResponse) {
// do stuff
});
You can also just return a non-promise value from a .then handler and it is wrapped in a promise and returned to the outer chain so you can get the value in the next .then handler.
function test() {
$q.all(promises).then(function (response) {
return 123;
});
}
test().then(function (result) {
// result is 123
});
I'm happy to give a more specific answer if you're still confused. I'd just need a code sample from you and what you're trying to accomplish so I can help.

Using a function that returns a promise, inside a then() block

I have a promise chain as follows :
return performTaskA().
then(performTaskB).
then(performTaskC).
then(performTaskD).
then(performTaskE);
performTaskD is as follows :
function performTaskD() {
Model.something().
then(function(result) {
something something with result; //BREAKPOINT 1
});
}
When I run the promise chain above, BREAKPOINT 1 never gets hit and the control proceeds to performTaskE.
However, when I call the function performTaskD() separately, BREAKPOINT 1 does get hit. What am I doing wrong in the case of the promise chain?
If I return the promise in performTaskD, I still have the same issue. The only difference is that the control never proceeds to performTaskE and the process exits.
For clarity, performTaskD is as follows :
AccountModel.findById(acctId).
then(function (account) {
destAccount = account; //destAccount is a var declared in the outer scope.
});
return the Promises
function performTaskD() {
return Model.something().
then(function(result) {
return something something with result; //BREAKPOINT 1
});
}
According to Mongoose documentation Model.find(something) does not return a promise. You need to call Model.find(something).exec(). The performTaskD should be something like:
function performTaskD(AcctId) {
return AccountModel.findById(AcctId).exec().
then(function (account) {
destAccount = account;
return account;
});
}
"then" function is called when a promise is resolved. In your task functions, you handle the promise inside the function itself, so the rest of the chain's "then" doesnt gets called.
Use Promise.resolve
function performTaskD() {
return Model.something().
then(function(result) {
something something with result; //BREAKPOINT 1
Promise.resolve(result)
});
}

Return from a promise then()

I have got a javascript code like this:
function justTesting() {
promise.then(function(output) {
return output + 1;
});
}
var test = justTesting();
I have got always an undefined value for the var test. I think that it is because the promises are not resolved yet..there is a way to return a value from a promise?
When you return something from a then() callback, it's a bit magic. If you return a value, the next then() is called with that value. However, if you return something promise-like, the next then() waits on it, and is only called when that promise settles (succeeds/fails).
Source: https://web.dev/promises/#queuing-asynchronous-actions
To use a promise, you have to either call a function that creates a promise or you have to create one yourself. You don't really describe what problem you're really trying to solve, but here's how you would create a promise yourself:
function justTesting(input) {
return new Promise(function(resolve, reject) {
// some async operation here
setTimeout(function() {
// resolve the promise with some value
resolve(input + 10);
}, 500);
});
}
justTesting(29).then(function(val) {
// you access the value from the promise here
log(val);
});
// display output in snippet
function log(x) {
document.write(x);
}
Or, if you already have a function that returns a promise, you can use that function and return its promise:
// function that returns a promise
function delay(t) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve();
}, t);
});
}
function justTesting(input) {
return delay(100).then(function() {
return input + 10;
});
}
justTesting(29).then(function(val) {
// you access the value from the promise here
log(val);
});
// display output in snippet
function log(x) {
document.write(x);
}
What I have done here is that I have returned a promise from the justTesting function. You can then get the result when the function is resolved.
// new answer
function justTesting() {
return new Promise((resolve, reject) => {
if (true) {
return resolve("testing");
} else {
return reject("promise failed");
}
});
}
justTesting()
.then(res => {
let test = res;
// do something with the output :)
})
.catch(err => {
console.log(err);
});
Hope this helps!
// old answer
function justTesting() {
return promise.then(function(output) {
return output + 1;
});
}
justTesting().then((res) => {
var test = res;
// do something with the output :)
}
I prefer to use "await" command and async functions to get rid of confusions of promises,
In this case I would write an asynchronous function first,
this will be used instead of the anonymous function called under "promise.then" part of this question :
async function SubFunction(output){
// Call to database , returns a promise, like an Ajax call etc :
const response = await axios.get( GetApiHost() + '/api/some_endpoint')
// Return :
return response;
}
and then I would call this function from main function :
async function justTesting() {
const lv_result = await SubFunction(output);
return lv_result + 1;
}
Noting that I returned both main function and sub function to async functions here.
Promises don't "return" values, they pass them to a callback (which you supply with .then()).
It's probably trying to say that you're supposed to do resolve(someObject); inside the promise implementation.
Then in your then code you can reference someObject to do what you want.
I think what the original poster wants is to return an unwrapped value from a promise without actually returning another promise. Unless proven otherwise, I'm afraid this is not possible outside of a then() or async/await context. You always get a promise no matter what.
You need to make use of reference data type like array or object.
function foo(u,n){
let result = [];
const userBrands = new Promise((res, rej)=> {
res(['brand 1', 'brand 3']);
})
userBrands.then((ub)=>{
return new Promise((res, rej) =>{
res([...ub, 'brand 4', 'brand 5']);
})
}).then(response => {
return result.push(...response);
});
return result;
};
foo();
You cannot return value after resolving promise. Instead call another function when promise is resolved:
function justTesting() {
promise.then(function(output) {
// instead of return call another function
afterResolve(output + 1);
});
}
function afterResolve(result) {
// do something with result
}
var test = justTesting();

Categories

Resources