3

jQueryDeferred系统的一种用途是使用$.when()函数。它需要可变数量的Promise's and will do something when they allresolve (or when the firstreject`s。)

因此,如果您想对两个 AjaxJSON查询进行操作,例如,您可以这样做:

var funkyPromise = $.getJSON('http://funky.json.service.com');
var awesomePromise = $.getJSON('http://awesome.json.service.com');

$.when(funkyPromise, awesomePromise).then(function() {
  /* do something amazing with the two objects */
}, function() {
  /* at least one of the services failed this time */
});

使用 jQuery 系统可以做的另一件事是在最终使用它之前,通过使用该方法将数据从一个到另一个Deferred“链接”来创建数据管道:Deferredpipe

$.getJSON('http://funky.json.service.com')
  .pipe(funkytoFunkier);
}).done(function(funkyData) {
    /* we now have a funkier version of what the web service gave us */
});

一切都奇妙地异步和解耦。

但是,如果我想$.when()在两个 asynchronous Promises 上使用,但我们还没有其中一个,因为它将pipe异步通过,会发生什么?

var funkyPromise = $.getJSON('http://funky.json.service.com');
var awesomePromise = $.getJSON('http://awesome.json.service.com');

// run "funky" through an asynchronous "pipe" to get "funkier"
//
// ... but ... how ??

$.when(funkyier, awesome).then(function() {
  /* do something amazing with the two objects */
}, function() {
  /* at least one of the services failed this time */
});

那么中间部分是什么?

  • 是不是很明显,我就是看不到?
  • 有没有可能,但有些微妙和棘手?
  • 一些新的“倒置”等价物pipe()$.when()让它更容易吗?
4

2 回答 2

3

pipe()返回一个新的 Promise,当管道被解析时,它会被解析,所以你只需要写:

var funkyPromise = $.getJSON('http://funky.json.service.com');
var awesomePromise = $.getJSON('http://awesome.json.service.com');

$.when(funkyPromise.pipe(funkytoFunkier), awesomePromise).then(function() {
  /* do something amazing with the two objects */
}, function() {
  /* at least one of the services failed this time */
});

请注意,从 jQuery 1.8 开始,与 jQuerythen()做同样的事情pipe(),因此这两种方法基本上是可以互换的。

于 2012-09-05T14:36:48.467 回答
1

@Frédéric Hamidi 知道正确的答案,但我必须弄清楚(-:这是一个小例子,我在 Frédéric 写下他的答案之后但在我阅读之前开始工作:

>> jsFiddle ...

function foo() {
    var time = Math.floor(Math.random() * 3000),
        d = $.Deferred();

    console.log('foo starting: ' + time);
    setTimeout(function() {
        console.log('foo resolving');
        d.resolve(time);
    }, time);

    return d.promise();
}

function bar() {
    var time = Math.floor(Math.random() * 500),
        d = $.Deferred();

    console.log('bar starting: ' + time);
    setTimeout(function() {
        console.log('bar resolving');
        d.resolve(time);
    }, time);

    return d.promise();
}

function baz(previousTime) {
    var time = Math.floor(Math.random() * 500),
        d = $.Deferred();

    console.log('baz starting: ' + time);
    setTimeout(function() {
        console.log('baz resolving');
        d.resolve(previousTime + ' + ' + time + ' = ' + (previousTime + time));
    }, time);

    return d.promise();
}

$.when(foo(), bar().pipe(baz))
    .then(function(foo, barBaz) {
        console.log('when OK', [foo, barBaz]);
    });​
于 2012-09-05T16:06:51.613 回答