我考虑使用promises将现有的基于回调的代码重写为代码。但是我不确定这是否有意义以及如何开始。以下代码片段是该代码中大部分自包含的示例:
function addTooltip($element, serverEndpoint, data) {
'use strict';
const DELAY = 300;
const TOOLTIP_PARENT_CLASS = 'hasTooltip';
let timeOutReference;
$element.hover(function hoverStart() {
if ($element.hasClass(TOOLTIP_PARENT_CLASS)) {
return;
}
timeOutReference = setTimeout(function getToolTip() {
const $span = jQuery('<span class="serverToolTip">');
$span.html(jQuery('<span class="waiting">'));
$element.append($span);
$element.addClass(TOOLTIP_PARENT_CLASS);
jQuery.get(serverEndpoint, data).done(function injectTooltip(response) {
$span.html(response.data);
}).fail(handleFailedAjax);
}, DELAY);
}, function hoverEnd() {
clearTimeout(timeOutReference);
});
};
预期功能:当用户将鼠标悬停在$element
上300ms时,会从服务器请求工具提示内容并附加到$element
。
用promises重写代码是否有意义,我该怎么做?
(jQuery由框架(dokuwiki)提供,所以我们也可以使用它。)
答案 0 :(得分:2)
首先,您需要将setTimeout
包含在承诺中。只需创建一个接受超时的函数,并返回在超时后解析的promise。
接下来,由于jQuery.get
已经返回了一个promise,你只需要将它放在promise resolve处理程序中并返回它的promise。这样,下一个链接then
会听取该承诺而不是计时器。
看起来像是:
function timer(n){
return Promise(function(resolve){
setTimeout(resolve, n);
});
}
timer(DELAY).then(function(){
return jQuery.get(...)
}).then(function(response){
// jQuery.get promise resolved
}).catch(function(error){
// something failed somewhere
});
关于你的问题
用promises重写代码是否有意义,我该怎么做?
这取决于你。我发现基于promise的代码更具可读性,但需要时间才能正确编写,特别是如果你打算编写纯回调并处理多个异步操作。我通常编写我的代码回调 - 如果API更容易编写,并且稍后重构以便于阅读。
答案 1 :(得分:1)
详细说明我的评论。下面是一个示例,说明promises如何使依赖回调代码(可以说)更具可读性(基本上,它会破坏回调中的回调嵌套):
同样,在您发布的代码段的情况下,我几乎看不出它的价值(除非您将其作为练习)。
使用回调
function someAsyncMethod(callback) {
$.get({...})
.then(callback);
}
function anotherAsyncMethod(callback) {
$.get({...})
.then(callback);
}
someAsyncMethod(function() {
anotherAsyncMethod(function yourFunction() {
//do something
});
});
承诺:
function someAsyncMethod() {
return $.get({...});
}
function anotherAsycnMethod() {
return $.get({...});
}
someAsyncMethod()
.then(anotherAsyncMethod)
.then(function yourFunction() {
//do something
})