19

我一直在阅读有关 jQuery 中的延迟和承诺,但我还没有使用它。

除了方法管道,我已经很好地理解了一切。我真的不明白它是什么。

有人可以帮助我了解它的作用以及可以在哪里使用吗?

我知道有一个问题的标题与这个(这里)完全一样,但它不一样。我正在寻求帮助以理解它和一些例子。另一个问题的目的是了解为什么它在特定情况下不起作用。

4

3 回答 3

47

基本上,Deferred.pipe()是异步的$.map()等价物。它从作为输入提供的其他值投射新值,但其目的是与延续一起使用。

让我们从一个只需要$.each()并发出返回简单对象的 AJAX 请求的示例开始。对于该对象的每个属性,我们希望其id属性为属性键的表单控件将其值设置为属性值。我们可以这样写:

$.ajax("your/url", {
    dataType: "json"
}).done(function(data) {
    $.each(data, function(key, value) {
        $("#" + key).val(value);
    });
});

现在假设我们想在更新表单控件之前对值应用一些函数。如果我们在本地这样做,我们只需要编写:

$.ajax("your/url", {
    dataType: "json"
}).done(function(data) {
    $.each(data, function(key, value) {
        // doSomethingWith() projects values synchronously, as map() does.
        $("#" + key).val(doSomethingWith(value));
    });
});

但是,如果doSomethingWith()不是在客户端实现,而是通过另一个 Web 服务在服务器端实现,会发生什么?在这种情况下,我们希望将控制流链接到第二个 AJAX 请求中,并且仅在第二个请求返回时更新表单控件。Deferred.pipe()让这很容易:

$.ajax("your/url", {
    dataType: "json"
}).pipe(function(theOriginalData) {
    return $.ajax("your/web/service/doSomethingWith", {
        data: theOriginalData,
        dataType: "json"
    });
}).done(function(theFinalData) {
    $.each(theFinalData, function(key, value) {
        $("#" + key).val(value);
    });
});
于 2012-04-20T21:19:21.540 回答
11

好的,我在这里的另一个答案中看到了很多参考资料,但是阅读有时不等于理解。

我发现最容易想到 Promise 和 .done() 对它的应用与 .pipe() 对它的应用。每个人的行为都不一样。如果我采用 promise.done(function (result) { ... }) 那么我可以在之后添加更多的 .done() 或 .fail(),因为每次调用 .done() 或 .fail( ) 返回完全相同的承诺。因此,每个函数都将与原始承诺相关联,以及它是否被解决或拒绝。

现在,将其与 .pipe() 进行对比。如果我接受 promise.pipe(function (result) { ...}) 那么 .pipe() 的结果就是一个全新的承诺!如果我随后将 .done() 或 .fail() 附加到该承诺,那么这些函数将获得 .pipe() 返回的结果的修改版本,而不是原始结果。

所以 .pipe() 根据我的经验,很少需要。它真正派上用场的唯一时间是,如果您需要在其他代码看到它之前修改从承诺返回的数据(例如,在任何其他客户端代码使用之前修改客户端 AJAX 调用的某些结果)它)或者如果您需要对事物进行排序。例如,在 Promise A 解决或拒绝之后,采取另一个行动,然后只有当这完成后,我们才希望其他代码最终触发。所有其他代码都附加到来自 .pipe() 调用的承诺 B。

这是一个最近的问题,另一个用户在使用 Promise 和 .pipe()/.done()/.when() 时遇到问题,我试图提供一些代码来澄清 jsFiddle 中每个用户的使用:Do something when所有延期都已解决

于 2012-04-20T21:19:49.377 回答
1

嗨,这就是你要找的东西:)

[很好读] http://www.bennadel.com/blog/2255-Using-jQuery-s-Pipe-Method-To-Change-Deferred-Resolution.htm

引用

pipe() 方法为(AJAX 请求的)成功和失败解决方案提供了一个过滤器。如果原始解析成功,则 pipe() 过滤器要么传递真正成功的响应;或者,它改变决议,返回一个新的被拒绝的承诺。然后,如果原始请求失败,这在我们的 API 中确实是出乎意料的,那么 pipe() 过滤器只会通过规范化的 API 响应结构......

带有示例的堆栈链接 了解 jQuery Deferred.pipe()(其中包含 jsfiddle)

了解延期和承诺?请看这里 http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

Jquery官方API页面 http://api.jquery.com/deferred.pipe/ (附示例)

描述:过滤和/或链接延迟的实用方法。

deferred.pipe() 方法返回一个新的 promise,它通过函数过滤 deferred 的状态和值。doneFilter 和 failFilter 函数过滤原始 deferred 的已解决/已拒绝状态和值。从 jQuery 1.7 开始,该方法还接受一个 progressFilter 函数来过滤对原始 deferred 的 notify 或 notifyWith 方法的任何调用。

于 2012-04-20T20:43:08.377 回答