最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is value undefined at .then() chained to Promise? - Stack Overflow

programmeradmin1浏览0评论

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?
})

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?

Share Improve this question asked Jun 8, 2017 at 15:15 guest271314guest271314 1 4
  • This Question/Answer is intended to be canonical. There have been several question where this specific pattern, that it, the omission of returning a value from function call or .then() has been the issue, including Run JavaScript promises in order. One after the other ends promise tag efficianodos do chime in, or not, if so inclined. – guest271314 Commented Jun 8, 2017 at 15:17
  • 2 Possible duplicate of: Promise returns undefined – Washington Guedes Commented Jul 13, 2017 at 11:01
  • @washington guedes this is a canonical answer. Only flag as duplicate if you find a real good one. ( not sth like try this ) – Jonas Wilms Commented Jul 15, 2017 at 11:04
  • Related return Json.Stringfy result, Why is my function returning undefined?, Fetch API - returned variable undefined, $.getJSON return/scope issue?, How to return value from a Promise – guest271314 Commented Jul 16, 2017 at 22:21
Add a comment  | 

6 Answers 6

Reset to default 17

Because no Promise or other value is returned 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 returns 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.

You must return the result from the .then() chained to the Promise. In your case just add

return result;

to the first .then().

发布评论

评论列表(0)

  1. 暂无评论