为什么 .then() 处的值未定义链接到 Promise?

新手上路,请多包涵

鉴于

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

为什么 data undefined.then() doStuff()

原文由 guest271314 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 348
2 个回答

Because no Promise or other value is return ed from .then() chained to Promise constructor.

请注意 .then() 返回一个新的 Promise 对象。

该解决方案 Promise return 一个值或其他函数调用,该调用 .then() return

 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`
});

原文由 guest271314 发布,翻译遵循 CC BY-SA 3.0 许可协议

面临的问题是:

 return
(new Promise(..)) //the promise we want to return
.then(()=>undefined) // the promise were actually returning, which resolves to undefined

正如您可能已经注意到的, then 返回一个新的承诺。这是有充分理由的,它使承诺链接变得容易,例如:

 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

但这也造成了我们面临的小陷阱。解决方案可能是返回 _原始承诺_,而不是 .then() 自动返回的 _新承诺_,因为这被解析为未定义,因为 then 中的函数没有明确返回一些东西:

 //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  :)

因此,正如您所见,要返回原始承诺,我们只需将其存储在一个变量中,然后为其分配一个 .then 处理程序,并且仍然有一个对原始承诺的引用,我们可以将其分配给其他处理程序(或 return )。

在行动中:

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

原文由 Jonas Wilms 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题