tôi đã thực hiện một số thí nghiệm sáng nay, trước khi đi để xem nếu tôi có một câu trả lời ... :-)
Bạn có thể nhìn thấy chúng ở http://plnkr.co/edit/3Xczzw
tôi phát hiện ra rằng concat của quan sát sẽ chạy mỗi lần lượt theo dõi, theo thứ tự đã cho.
var o1 = Rx.Observable.interval(1500).take(1).map(function (i) { return { n: i, id: 'First', ts: Date.now() - reference }});
var o2 = Rx.Observable.interval(1000).take(2).map(function (i) { return { n: i, id: 'Second', ts: Date.now() - reference }});
var o3 = Rx.Observable.interval(2000).take(1).map(function (i) { return { n: i, id: 'Third', ts: Date.now() - reference }});
// Alternative
var oa = Rx.Observable.timer(1200).map(function (i) { return { n: i, id: 'Alternative', ts: Date.now() - reference }});
Rx.Observable.concat(o1, o2, o3, oa).subscribe(
function onNext(v) { v.timestamp = Date.now() - reference; showObject(v); },
function onError(e) { var ts = Date.now() - reference; showHTML("Error " + JSON.stringify(e) + " at " + ts); },
function onCompleted() { var ts = Date.now() - reference; showHTML("Completed at " + ts); }
);
cho
{"n":0,"id":"First","ts":1503,"timestamp":1503}
{"n":0,"id":"Second","ts":2504,"timestamp":2504}
{"n":1,"id":"Second","ts":3505,"timestamp":3505}
{"n":0,"id":"Third","ts":5506,"timestamp":5506}
{"n":0,"id":"Alternative","ts":6708,"timestamp":6708}
Completed at 6708
Một concat những lời hứa sẽ không cung cấp bất cứ điều gì trước lời hứa đầu tiên giải quyết. Sau đó, nó có thể cung cấp (tức là gọi onNext) các lời hứa khác đã giải quyết, vẫn theo thứ tự đã cho. Sau đó có thể chờ đợi lời hứa tiếp theo nếu có hài cốt vv
var p1 = promiseInTime(1500, { id: 'First'});
var p2 = promiseInTime(1000, { id: 'Second' });
var p3 = promiseInTime(2000, { id: 'Third' });
var pa = promiseInTime(1200, { id: 'Failed? ' + !!withFailure }, withFailure);
Rx.Observable.concat(p1, p2, p3, pa).subscribe(
function onNext(v) { v.timestamp = Date.now() - reference; showObject(v); },
function onError(e) { var ts = Date.now() - reference; showHTML("Error " + JSON.stringify(e) + " at " + ts); },
function onCompleted() { var ts = Date.now() - reference; showHTML("Completed at " + ts); }
);
cho
{"id":"First","promiseTimeout":1500,"timestamp":1501}
{"id":"Second","promiseTimeout":1000,"timestamp":1506}
{"id":"Third","promiseTimeout":2000,"timestamp":2001}
Error {"id":"Failed? true","promiseTimeout":1201} at 2004
hoặc
{"id":"First","promiseTimeout":1500,"timestamp":1501}
{"id":"Second","promiseTimeout":1000,"timestamp":1503}
{"id":"Third","promiseTimeout":2000,"timestamp":2000}
{"id":"Failed? false","promiseTimeout":1201,"timestamp":2004}
Completed at 2004
Vì vậy, về cơ bản, concat tôn trọng trật tự của đối số của nó, có thể là một cách để tìm lại yêu cầu nào đã đưa ra kết quả hứa hẹn.
Trong trường hợp của các yêu cầu Ajax, tốt hơn concat những lời hứa hơn quan sát, vì chúng sẽ được yêu cầu song song, không tuần tự (trừ khi bạn cần thứ hai, tất nhiên).
Tôi đã thử giải pháp được đưa ra bởi @ user3743222 và đây là một giải pháp hay. Tôi thích forkJoin, vì các kết quả được gán rõ ràng cho các tham số, thay vì dựa vào thứ tự.
Bạn phải nhận thức được sự khác biệt trong quản lý lỗi: Tôi phát hiện ra rằng concat sẽ xử lý tất cả các lời hứa, cho đến khi tìm thấy lỗi đầu tiên. Trong khi forkJoin sẽ không xử lý bất cứ điều gì nếu một trong những lỗi hứa hẹn. Điều này có ý nghĩa (chúng tôi không thể tham gia một phần kết quả, nói chung).
Cảm ơn. Tôi tìm ra cách concat thực sự hoạt động (xem câu trả lời của tôi), nhưng tôi thích forkJoin, tương ứng với những gì tôi muốn. Tôi hoàn toàn bỏ qua này ... :-) – PhiLho
Nếu ai đó đang cố gắng để làm việc trong Angular, nó sẽ không, như "hoàn thành" sự kiện không được kích hoạt từ các quan sát http. Đối với một giải pháp tương tự, nó đã làm việc cho tôi bằng cách sử dụng "combinedLatest" thay thế. – frandevel