【问题标题】:What is the difference in jQuery between returning deferred and deferred.promise()?jQuery 返回 deferred 和 deferred.promise() 有什么区别?
【发布时间】:2022-01-03 10:30:59
【问题描述】:

我正在使用 jQuery 的 ES5 环境中工作。我有一些代码如下:

var saveGame = function (gameState, saveStars) {
  var deferred = $.Deferred();
  var starsSaved = saveStars ? false : true;

  model.game().saved(starsSaved);
  model.driveAccessInProgress(true);

  GW.manifest.saveGame(gameState).then(function () {
    model.driveAccessInProgress(false);
    deferred.resolve();
  });
  return deferred; // or deferred.promise()?
};

saveGame().then(/* more stuff */);

在这种情况下,无论我返回 deferred.promise() 还是仅返回 deferred.then 都会按预期工作。鉴于此,我想我有点不清楚什么是承诺,并且想知道这两个回报之间有什么区别以及什么时候可能重要?

【问题讨论】:

  • 不回答你的问题,但看起来GW.manifest.saveGame(gameState) 已经返回了一个 Promise(like?) 对象。如果您的代码使用deferred.resolve(); 可能会被视为反模式。
  • 我是否理解正确,您的意思是在 GW.manifest.saveGame() 解决之前该功能不会完成,因此添加 $.Deferred() 是没有意义的,因此很糟糕?由于函数必须为后来的.then() 返回一些东西,我该怎么办?
  • 如果 GW.manifest.saveGame 已经创建了一个 Promise,那么使用 $.Deferred() 构建一个新的 Promise 是一种反模式。 $.Deferred() 只能用于将不基于 Promise 的内容转换为基于 Promise 的版本。否则,您基本上会打破一个承诺链并创建一个新的承诺链。 ...

标签: javascript jquery jquery-deferred


【解决方案1】:

您希望返回 deferred.promise() 以便调用代码无法调用 resolve 或 reject 或其他特定于 Deferred 的方法。这不是调用者应该有权访问的东西。它应该只能消费 promise,而不影响它的状态。 您也可以阅读documentation

【讨论】:

  • 我读到了,但当时并没有理解它的含义。我是否认为如果我返回 deferredsaveGame().reject() 是有效的,但如果我返回 deferred.promise() 则它不会是正确的?
【解决方案2】:

你会返回deferred.promise()

但看起来saveGame(gameState) 已经返回了一个Promise,所以你根本不应该在这里使用$.Deferred

var saveGame = function (gameState, saveStars) {
  var starsSaved = saveStars ? false : true;

  model.game().saved(starsSaved);
  model.driveAccessInProgress(true);

  return GW.manifest.saveGame(gameState).then(function () {
    model.driveAccessInProgress(false);
  });
};

saveGame().then(/* more stuff */);

已经有一个 Promise 并使用 $.Deferred 创建一个新的 Promise 是一种反模式。这样做的原因是您可能很容易忘记某些情况,并且您的代码可能会卡在这一点上。

如果GW.manifest.saveGame(gameState) 失败?您不考虑这种情况,因此您需要添加.catch

  GW.manifest.saveGame(gameState).then(function () {
    model.driveAccessInProgress(false);
    deferred.resolve();
  })
  .catch(function(err) {
    deferred.resolve(err);
  })

可能还有其他情况。

【讨论】:

    猜你喜欢
    • 2011-09-29
    • 2011-12-24
    • 2012-03-22
    • 2016-06-28
    • 2017-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    相关资源
    最近更新 更多