Given
function doStuff(n /* `n` is expected to be a positive number */) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(n * 10)
}, Math.floor(Math.random() * 1000))
})
.then(function(result) {
if (result > 100) {
console.log(result + \" is greater than 100\")
} else {
console.log(result + \" is not greater than 100\");
}
})
}
doStuff(9)
.then(function(data) {
console.log(data) // `undefined`, why?
})
Why is data
undefined
at .then()
chained to doStuff()
call?
Because no Promise
or other value is return
ed from .then()
chained to Promise
constructor.
Note that .then()
returns a new Promise
object.
The solution is to return
a value or other function call which return
s a value or Promise
from .then()
.
function doStuff(n /* `n` is expected to be a positive number */) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(n * 10)
}, Math.floor(Math.random() * 1000))
})
.then(function(result) {
if (result > 100) {
console.log(result + \" is greater than 100\")
} else {
console.log(result + \" is not greater than 100\");
}
// `return` `result` or other value here
// to avoid `undefined` at chained `.then()`
return result
})
}
doStuff(9)
.then(function(data) {
console.log(\"data is: \" + data) // `data` is not `undefined`
});
The problem were facing:
return
(new Promise(..)) //the promise we want to return
.then(()=>undefined) // the promise were actually returning, which resolves to undefined
As you may already noticed, then returns a new promise. This has a good reason, it makes promise chaining easy, e.g:
getUser()//an asynchronous action
.then(user=>login(user))//then if we get the user,promise to log in
.then(token=>console.log(\"logged in,token is \"+token) //then if we logged in, log it
.catch(error=>\"login failed\");//catch all errors from above
But this also creates the small trap, we are facing. The solution could be returning the original promise and not the new promise automatically returned by .then() as this is resolved to undefined as the function inside then is not explicitly returning something:
//what were doing:
Promise.resolve(n*10)//the original promise resolves to n*10
.then(a=>undefined)//the then gets n*10 passed as a, but returns undefined
.then(b=>console.log(b));//b will be undefined :0
//what we want:
var promise=Promise.resolve(n*10);
promise.then(a=>undefined);//a is n*10, this resolves to undefined
promise.then(b=>console.log(b));//but this still logs n*10, as its the original promise :)
So as you can see, to return the original promise, we simply store it in a variable, then assign a .then handler to it, and have still a reference to the original promise which we can assign other handlers to ( or return ).
In action:
function doStuff(n /* `n` is expected to be a number */) {
//create a new promise and store it
var promise=new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(n * 10)
},1000);
});
//add a then handler to this promise
promise.then(result=>console.log(result + \" is \"+result<100?\"not\":\"\"+\" greater than 100\"));
//return the original one
return promise;
}
doStuff(9).then(function(data) {
console.log(data) //not undefined, as original promise
})
The doStuff is returning the Promise
. But, your last then
function is not returning any values, hence data
is coming as undefined
.
In promises, value of arguments of the next then
function is the returned value of the previous then
function.
function doStuff(n /* `n` is expected to be a positive number */) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(n * 10)
}, Math.floor(Math.random() * 1000))
})
.then(function(result) {
if (result > 100) {
console.log(result + \" is greater than 100\")
} else {
console.log(result + \" is not greater than 100\");
}
return result;
})
}
doStuff(9)
.then(function(data) {
console.log(data) // `90`
})
You are not returning the result from the .then() chained to the Promise. You need to add return result; to the .then()
Because your data value is the return value of the last .then()
, your last .then()
doesn\'t have a valid return value.
So, you can add the return value in the last .then()
function.