我有两个JS函数,都返回jQuery
的promise
,假设它们是:getServerTimestamp()
和比如doSomething()
。getServerTimestamp()
在第一次调用时基本上
1.通过ajax获取服务器上的当前时间
1.计算出本地时间和服务器时间之间的差异
1.本地存储时差
1.使用deferred.resolve()
返回服务器时间
如果稍后再次调用getServerTimestamp()
,它将检查是否存储了时差。
- 如果是,则使用存储的时间差计算服务器时间,并使用
deferred.resolve()
返回计算的服务器时间 - 如果没有,它将像第一次被调用一样运行。
所以我必须在一个依赖于getServerTimestamp()
的函数中调用doSomething()
,因为getServerTimestamp()
返回promise
,所以我还必须为函数返回一个promise
,简而言之,我的函数看起来有点像这样:(我承认我不是很擅长处理多个deferred
和promise
。)
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()
的错误了,但是我觉得这样写代码要写两遍,或者我应该忘记这样做会造成混乱,还有更优雅的选择吗?
1条答案
按热度按时间4szc88ey1#
我强烈建议不要用
isTimeDifferenceReady()
函数跟踪promise的状态。这会给你的代码增加很多不必要的复杂性。Promise的一个优点是,它们允许调用者 * 不 * 担心状态问题,比如是否需要获取一些数据。调用者可以依赖这样一个事实,即当数据可用时,Promise将进行解析;并且可以几乎立即或在较长时间之后。但是,我们可以简化您的
myFunction
。由于
getTimestamp
和doSomething
已经返回了一个延迟承诺,我们不需要在myFunction
中创建一个新的延迟承诺。此外,我不认为myFunction
中的错误处理程序有任何价值,因为它们只是记录错误,然后重新拒绝它。如果我们删除这些处理程序,调用者仍然需要处理这些错误。因此,如果
myFunction
被简化为:唯一的行为变化是,如果
getServerTimestamp
或doSomething
拒绝一个错误,则不记录错误。如果确实希望myFunction
记录错误,可以使用以下命令:Here是示例小提琴。