如何以及何时将jQuery回调重写为promises?

时间:2017-02-27 13:00:55

标签: javascript jquery promise

我考虑使用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)提供,所以我们也可以使用它。)

之前的研究:

2 个答案:

答案 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
  })