是否存在jQuery API的异步/承诺变体



我将jQuery的.click()封装在这个函数中,该函数返回Promise:

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

有没有比将jQuery的回调API全部封装在这些函数中更好的方法来适应Promise?

是否有更好的方法使jQuery的回调API适应Promise,而不是将所有这些函数包装在这些函数中?

首先,jQuery已经包含了一些对完成通知的promise支持。例如,如果您有兴趣了解动画何时完成,那么他们有.promise(),它会在特定对象的fx动画队列完成时解析。这些类型的操作是一次性通知,与承诺的工作方式非常匹配。

jQuery还内置了对ajax调用的promise支持,您可以使用它们的回调接口,也可以使用jQuery ajax的promise接口。

jQuery没有任何内置的promise支持,可以支持重复发生的事件(如按钮点击(,因为它们与promise的一次性功能不直接匹配。

因此,如果你真的想在下一次点击某个特定元素时使用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。再多写几行代码,就可以用普通的DOMJavascript实现同样的功能。


如果您一次只打算将其用于一个元素,并且只传递一个与一个元素完全匹配的选择器,那么您可以使用.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);
});
}

最新更新