2016-09-22 63 views
3

想象一下,我們有一個觸發AJAX請求的HTML頁面。我們希望確保AJAX請求按順序執行。直到前一個AJAX請求完成或發生錯誤,下一個AJAX請求才會被觸發。RxJS 5任務隊列,如果任務失敗則繼續

我試圖通過使用RxJS concatMap的任務隊列對此進行建模。每個AJAX請求都被建模爲Observable。如果AJAX請求成功完成,一切都很好,但是如果錯誤發生,那麼隊列中的下一個任務就不會執行。

下面是一個例子,使用setTimeout()模擬長時間運行的異步任務:

function identity(observable) { 
    return observable; 
    } 

    function createTaskQueue() { 
    var subject= new Rx.Subject(); 

    subject 
    .concatMap(identity) 
    .onErrorResumeNext(Rx.Observable.of('error')) 
    .subscribe(function(data) { 
     console.log('onNext', data); 
    }, 
    function(error) { 
     console.log('onError', error); 
    }); 

    return { 
     addTask: function(task) { 
     subject.next(task); 
     } 
    } 
    } 

    function createTask(data, delay) { 
    return Rx.Observable.create(function(obs) { 
     setTimeout(function() { 
     obs.next(data); 
     obs.complete(); 
     }, delay); 
    }); 
    } 

    function createErrorTask(data, delay) { 
    return Rx.Observable.create(function(obs) { 
     setTimeout(function() { 
     obs.error('Error: ' + data); 
     obs.complete(); 
     }, delay); 
    }); 
    } 

    var taskQueue = createTaskQueue(); 

    taskQueue.addTask(createTask(11, 500)) 
    taskQueue.addTask(createTask(22, 200)); 
    taskQueue.addTask(createErrorTask(33, 1000)); 
    taskQueue.addTask(createTask(44, 300)); 
    taskQueue.addTask(createErrorTask(55, 300)); 
    taskQueue.addTask(createTask(66, 300)); 

下面是一個可執行的例子:https://jsfiddle.net/artur_ciocanu/s6ftxwnf/

當我運行這段代碼下面是打印到控制檯: onNext 11 onNext 22 onNext error

這是預期的,但我不知道爲什麼其他任務,例如44,55等不被執行。

我很確定我正在做一些與onErrorResumeNext()蠢事或可能是整個方法是完全錯誤的。

任何幫助,非常感謝。

回答

2

如果你讀的onErrorResumeNext文檔,

繼續是正常或由 例外下一個觀察的序列或承諾終止可觀察序列。

這意味着當您的源observable遇到錯誤時,它將切換到您傳遞給onErrorResumeNext的任何內容。這裏發生的是Rx.of(...)在發佈它的值後立即終止。因此你觀察到的行爲。

所以總之,你不想在這裏onErrorResumeNext

您可以改爲.catch(...)可能發出錯誤的流。所以,像這樣的:

subject 
    .concatMap(obs => obs.catch(Rx.Observable.of('error'))) 
    .subscribe(...) 
+1

謝謝!!!它像一個魅力。現在所有這些錯誤處理更有意義。 –

+1

很高興聽到。那麼你應該花時間接受一個答案,如果它適合你的話,並且如果它有用的話就UPVOTE。這是有效的答案,但也爲這一個:http://stackoverflow.com/questions/32594357/rxjs-modeling-if-else-control-structures-with-observables-operators,和這一個:http:// stackoverflow.com/questions/36914801/javascript-new-date-gettime-with-timezone-offset-calculations-returns-9-999 – user3743222

0

觀察對象中的錯誤的想法與常規函數中的一樣。意思是如果你在普通函數中拋出一個錯誤 - 函數不會返回任何東西。觀察對象也是如此 - 如果observable發出錯誤,那意味着流完成並且沒有更多的值來臨。所以是的,這是根本錯誤的。

更好的(正確)方法是獲得響應流,其中下一個值可以是成功響應或錯誤響應。如果您需要將它們分開,您可以在稍後將響應流分成兩個成功/錯誤響應。

希望有所幫助。

+1

感謝您的幫助。我在想這是一個壞主意,但我想知道社區有什麼要說的。 –