链接jQuery,已推迟

x4shl7ld  于 2023-02-21  发布在  jQuery
关注(0)|答案(1)|浏览(104)

我有两个JS函数,都返回jQuerypromise,假设它们是:getServerTimestamp()和比如doSomething()
getServerTimestamp()在第一次调用时基本上
1.通过ajax获取服务器上的当前时间
1.计算出本地时间和服务器时间之间的差异
1.本地存储时差
1.使用deferred.resolve()返回服务器时间
如果稍后再次调用getServerTimestamp(),它将检查是否存储了时差。

  • 如果是,则使用存储的时间差计算服务器时间,并使用deferred.resolve()返回计算的服务器时间
  • 如果没有,它将像第一次被调用一样运行。

所以我必须在一个依赖于getServerTimestamp()的函数中调用doSomething(),因为getServerTimestamp()返回promise,所以我还必须为函数返回一个promise,简而言之,我的函数看起来有点像这样:(我承认我不是很擅长处理多个deferredpromise。)

function myFunction() {
  var dfd = jQuery.Deferred();
  getServerTimestamp().then(
    function (serverTime) {
      doSomething().then(
        function (...) {
          ...
          dfd.resolve(...);
        },
        function (errorMessage) {
          ...
          console.log(errorMessage);
          dfd.reject(errorMessage);
        }
      );
    },
    function (errorMessage) {
      ...
      console.log(errorMessage);
      dfd.reject(errorMessage);
    }
  );
  return dfd.promise();
}

我认为用这种方式链接所有的承诺看起来有点笨拙,尤其是错误处理部分。我想知道是否有一种优雅的方式来做到这一点。
另一件我想到的事情是-因为getServerTimestamp() * 实际上 * 只调用一次ajax,它在第一次成功返回后就可以在本地解决所有问题,而不需要进一步调用ajax。就拥有好的代码而言,如果我分解并分解出getServerTimestamp(),然后像下面这样做,会不会是一个更好的实践?

function myFunction() {
  var dfd = jQuery.Deferred();
  if (isTimeDifferenceReady()) {
    doSomething(getServerTimestampFromLocal());
    dfd.resolve(...);
  } else {
    getServerTimestamp().then(function() {
      doSomething(serverTime);
      dfd.resolve(...);
    }, ...);
  }
  return dfd.promise();
}

这样的话,我就不用担心在不需要ajax调用的时候处理getServerTimestamp()的错误了,但是我觉得这样写代码要写两遍,或者我应该忘记这样做会造成混乱,还有更优雅的选择吗?

4szc88ey

4szc88ey1#

我强烈建议不要用isTimeDifferenceReady()函数跟踪promise的状态。这会给你的代码增加很多不必要的复杂性。Promise的一个优点是,它们允许调用者 * 不 * 担心状态问题,比如是否需要获取一些数据。调用者可以依赖这样一个事实,即当数据可用时,Promise将进行解析;并且可以几乎立即或在较长时间之后。
但是,我们可以简化您的myFunction
由于getTimestampdoSomething已经返回了一个延迟承诺,我们不需要在myFunction中创建一个新的延迟承诺。此外,我不认为myFunction中的错误处理程序有任何价值,因为它们只是记录错误,然后重新拒绝它。如果我们删除这些处理程序,调用者仍然需要处理这些错误。
因此,如果myFunction被简化为:

function myFunction() {
  return getServerTimestamp().then(doSomething);
}

唯一的行为变化是,如果getServerTimestampdoSomething拒绝一个错误,则不记录错误。如果确实希望myFunction记录错误,可以使用以下命令:

function myFunction() {
  return getServerTimestamp()
    .then(doSomething)
    .catch(err => {
      console.log(err);
      throw err;
    });
}

Here是示例小提琴。

相关问题