jQuery API是否有async / Promise变体?

时间:2019-11-01 21:55:24

标签: javascript jquery asynchronous promise

我在此函数中包装了jQuery的Dim rng As Range rng = Range("A9:K10").Text rng.Text = Replace(rng, "1st", "2nd") End Sub ,该函数返回了Promise:

.click()

是否有比将它们全部包装在这些函数中更好的方法来使jQuery的回调API适应Promises?

2 个答案:

答案 0 :(得分:2)

  

是否有比将它们全部包装在这些函数中更好的方法来使jQuery的回调API适应Promises?

首先,jQuery已经包含一些对完成通知的Promise支持。例如,如果您想知道动画何时完成,则他们拥有.promise(),该承诺可以解决特定对象的fx动画队列何时完成。这些类型的操作是一次性通知,非常适合诺言的工作方式。

jQuery还具有对ajax调用的内置Promise支持,您可以将其回调接口或jQuery Ajax的Promise接口使用。

jQuery对可能重复发生的事件(例如按钮单击)没有任何内置的Promise支持,因为它们不直接与Promise的一次性功能对齐。

因此,如果您真的想对下一个特定元素单击使用诺言,那么您将必须为此建立自己的诺言支持。

您建议的功能适用于某些输入参数:

function clickPromise(selector) {
  return new Promise((resolve, reject) => {
    $(selector).click((event) => resolve(event));
  });
}

例如,如果选择器仅匹配一个DOM元素,或者它匹配多个DOM元素,而您只希望对这些元素中的任何一个进行第一次单击,而这些元素不会持续很长时间,以至于您将其称为并再次使用相同的元素(它将随着时间的推移建立事件侦听器),那么就可以正常工作。

就个人而言,如果您打算这样做,我建议您这样做:

// Get promise for the very next click on any of 1 to many items
//    resolves when the first click happens
//    rejects if the selector doesn't match any elements
function clickPromise(selector) {
  return new Promise((resolve, reject) => {
    const items = $(selector);

    if (!items.length) {
        reject(new Error("selector empty"));
        return;
    }

    const handler = function(event) {
         // remove all event listeners we previously installed so they don't build up
         items.off('click', handler);
         resolve(event);
    }
    // install click handlers
    items.on('click', handler);
  });
}

与实现的主要区别在于,单击会在事件发生时删除事件侦听器,因此如果在同一元素上反复使用此函数,事件侦听器不会随着时间的推移而累积,并且如果选择器与任何元素都不匹配,则拒绝因为否则它将永远无法实现。

仅供参考,此类功能不依赖jQuery。再增加几行代码,就可以使用普通的DOM Javascript来实现相同的功能。


如果您一次只打算一次使用一个元素,并且只传递一个恰好匹配一个元素的选择器,则可以使用.one()使其更简单:

// Get promise for the very next click on any of 1 to many items
//    resolves when the first click happens
//    rejects if the selector doesn't match any elements
function clickPromise(selector) {
  return new Promise((resolve, reject) => {
    const items = $(selector);

    if (items.length === 0) {
        reject(new Error("selector empty"));
        return;
    } else if (items.length > 1) {
        reject(new Error("selector matches more than one element"));
        return;
    }

    items.one('click', function(event) {
        resolve(event);
    });
}

答案 1 :(得分:-2)

您可以使用与$deferred等效的jquery Promises对象。

https://api.jquery.com/category/deferred-object/

从文档中

// Existing object
var obj = {
    hello: function( name ) {
      alert( "Hello " + name );
    }
  },
  // Create a Deferred
  defer = $.Deferred();

// Set object as a promise
defer.promise( obj );

// Resolve the deferred
defer.resolve( "John" );

// Use the object as a Promise
obj.done(function( name ) {
  obj.hello( name ); // Will alert "Hello John"
}).hello( "Karl" ); // Will alert "Hello Karl"