【问题标题】:Return Promise result instead of Promise in Nodejs返回 Promise 结果而不是 Nodejs 中的 Promise
【发布时间】:2017-06-02 19:23:50
【问题描述】:

背景

我正在尝试学习 Promise,并且我有一个想要改进的 Promise 链。

问题

在学习如何链接 Promise 时,我不明白为什么有人宁愿返回 Promise 而不是返回它的值。

以下面的例子为例,它使用了 Promise 链:

let myObj = new MyClass();

myObj.getInfo()
    .then(result => writeOutput(FILE_NAME, result))
    .then(console.log(FILE_NAME + " complete"))
    .catch(error => console.error(error));

class MyClass{

    getInfo() {
        return new Promise(function(fulfil, reject) {
            fulfill("I like bananas");
        });
}

在这里我必须链接 2 次。但是,如果我直接从方法 getInfo() 返回结果而不是返回 Promise,我可能会执行以下操作:

let myObj = new MyClass();

let str = myObj.getInfo();

writeOutput(FILE_NAME, str)
    .then(console.log(FILE_NAME + " complete"))
    .catch(error => console.error(error));

问题

所以你可以看到我有点困惑。

  1. 鉴于getInfo() 实际上是异步的,是否可以实现与我的第二个代码示例中的代码类似的代码?
  2. 如果可能的话,这是个好主意吗?你会怎么做?

【问题讨论】:

    标签: javascript node.js promise


    【解决方案1】:

    您只能从某个函数返回一个值,如果该值在调用该函数时立即可用(在事件循环的同一滴答声上)。请记住,return 是同步的。

    如果它不能立即使用,那么您只能返回一个承诺(或者您可以使用回调,但在这里您专门询问承诺)。

    有关更详细的解释,请参阅我前段时间写的关于如何从某个函数返回 AJAX 调用结果的问题的答案。我解释了为什么你不能返回值但你可以返回一个承诺:

    这是另一个相关的答案 - 由于某种原因它被否决了,但我认为它解释了你问她的类似问题:

    【讨论】:

      【解决方案2】:

      我不明白为什么有人宁愿返回一个承诺而不是返回它的价值。

      因为你还没有价值。

      鉴于getInfo() 实际上是异步的,是否有可能实现与我的第二个代码示例中的代码类似的代码?

      如果它是异步的,它必须返回一个承诺。

      async/await 使避免then 调用(但仍使用并产生承诺)的语法成为可能:

      async function writeInfo(FILE_NAME) {
          const myObj = new MyClass();
          try {
              const str = await myObj.getInfo();
              await writeOutput(FILE_NAME, str);
              console.log(FILE_NAME + " complete");
          } catch (error) {
              console.error(error);
          }
      }
      writeInfo("…");
      

      【讨论】:

        【解决方案3】:

        promise 的目的是说:“数据会在某个时候出现,现在继续你的编码”,这样你的页面就不会卡住。基本上,您使用 Promises 例如从服务器加载某些内容。

        【讨论】:

          【解决方案4】:

          看待第一个问题的另一种方式(“为什么会有人……”):

          当您在一个 Promise 上调用 .then.catch 时,从调用返回的待处理 Promise 将附加到现有 Promise 链的末尾。 (允许“现有链”可能只包含一个承诺)。

          当你解决(不是“履行”,你不能用一个承诺来履行一个承诺)一个带有承诺的承诺时,在解决方案中使用的承诺插入到其余部分的头部承诺链。

          解析中使用的承诺必须在调用链中的下一个.then.catch 子句之前实现一个值。

          【讨论】:

            猜你喜欢
            • 2017-10-31
            • 2021-05-03
            • 2021-02-06
            • 2017-03-17
            • 1970-01-01
            • 1970-01-01
            • 2021-03-17
            • 2018-05-20
            • 1970-01-01
            相关资源
            最近更新 更多