【问题标题】:Do I have to fulfil my JavaScript promises?我必须履行我的 JavaScript 承诺吗?
【发布时间】:2015-07-24 15:19:49
【问题描述】:

如果我这样做,在Node.js 环境中:

var doNoResolve = true;

function a() {
    return new Promise(resolve => {
        if (doNotResolve) {
            return
        }
        resolve(10);
    });
}

a().then(() => {
    // I don't want this getting fired
});

对于传入的请求,这是内存泄漏吗?如果我使用的是一个普通的旧回调,那么如果我不执行提供的任何回调,一切都会变得很好,但这感觉可能不是......这个名字 promise 暗示这是有点不对。

如果必须的话,如果 doNotResolve 为真,我可以在 function a() 中返回“虚假承诺”(return { then: () => {} }),而不是“真实承诺”,但这感觉有点恶心。

特定的用例是同构 React.js 应用程序,我不希望实际发出 HTTP 请求(但我确实希望我的商店更新到导致加载图标的状态出现)。

【问题讨论】:

标签: javascript node.js es6-promise


【解决方案1】:

你为什么要这样做而不是拒绝?

promise 的好处是它们允许解决和拒绝,其中:

  1. 不触发 then 处理程序(除非您提供两个回调,这被认为是不好的做法)
  2. 会触发 catch 处理程序,它会显式处理错误
  3. 仍然触发 finally 处理程序

你可以这样做:

function a() {
    return new Promise((resolve, reject) => {
        if (doNotResolve) {
            reject(new Error('Oh noes!'));
        }
        resolve(10);
    });
}

任何好的Promise 实现都会从您调用reject 的位置为您提供堆栈跟踪,以帮助您调试异步代码,以及调用任何catch/finally 处理程序:

a().then(val => {
  console.log('Got data:', val);
}).catch(err => {
  console.error(err);
}).finally(() => {
  console.log('Done!');
});

从不拒绝或解决一个 Promise 会根据您的实现将其留在待处理的 Promise 堆栈中,并且很可能在您的页面卸载或节点 Promise 退出时抛出或记录错误。我知道如果你留下任何未决的承诺,Bluebird 会抱怨,因为它通常表明你的代码的异步部分存在错误。

【讨论】:

  • "除非您提供两个回调,否则这被认为是不好的做法" 您有支持该主张的文章吗?我很感兴趣。
  • @elad.chen 我记得在 Bluebird API 文档中看到过一些相关内容,但目前找不到。当我弄清楚我在哪里读到它时,我会引用一些东西,但getPromise().then(x).catch(y)then(x).then(null, y) 清晰得多,并且比then(x, y) 略好。
  • 因为我根本不希望 任何事情 发生(此时我想也许我不应该使用“承诺”?)。我想我可以拒绝它,然后抓住它,然后什么也不做,但似乎也好不到哪里去
  • @Joshua 在没有catch 处理程序的情况下拒绝是正确的,我相信。您仍然需要以一种或另一种方式告诉 Promise 它已完成,但没有什么要求您处理该拒绝。使用没有thencatch 的promise 是完全合理的。
  • 如果我拒绝它并且没有抓住它,错误将会传播并且进程将崩溃......
猜你喜欢
  • 1970-01-01
  • 2013-10-23
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 2016-01-27
  • 1970-01-01
  • 2015-11-17
相关资源
最近更新 更多