2012-09-05 26 views
3

jQuery的Deferred系統的一個用途是使用$.when()函數。它採用可變數量的Promise's and will do something when they all決心(or when the first reject`s)

所以,如果你想在兩個阿賈克斯JSON查詢,比如,你可以做的工作:

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做的另一件事系統是從一個Deferred通過另一使用方法pipe最終使用它之前通過「鏈」中的數據,使數據管道:

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

奇妙的異步和解耦。

但是,如果我想在兩個異步Promise的使用$.when()但我們沒有他們中的一個還沒有,因爲它會通過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()等等,使它更容易?
+0

它是可以接受的巢穴這些延期電話? – DrColossos

+0

@DrColossos:對於這個問題,我的頭繞過它,所以對於一些使用情況嵌套將是一個選項,也可能有用例,它不是我想要了解它沒有嵌套...如果可能的是( - : – hippietrail

回答

3

pipe()返回一個新的承諾,當管道被解決,這將得到解決,所以你只需要編寫:

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,then()開始做同樣的事情爲pipe() ,所以這兩種方法基本上是可以互換的。

+0

是的,你是完全正確的,我實際上已經過了幾個星期了(因爲我沒有完全理解所有的延期/異步/去耦問題),但是在完全寫下來之後,在海灘下沉了一會兒,我得出了相同的結論,它是完全無關緊要的。測試代碼進入答案... – hippietrail

1

@Frédéric Hamidi knew the right answer但我不得不弄清楚(-:這裏有一個簡單的例子,我有工作後弗雷德裏克寫了他的答案,但之前,我讀了:

>> 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]); 
    });​