RxJS отправляет несколько уникальных запросов ajax по событию

Если у меня есть тип события; скажем событие клика. Что я хочу запустить 3 уникальных запроса ajax, но я хочу подписаться на окончательный результат всех 3 запросов

Каков правильный шаблон проектирования для этой последовательности.

Мой текущий блок кода выглядит примерно так

$rootScope.$eventToObservable('selectUser')
    .throttle(500)
    .map(data => {
        return angular.copy(data.additionalArguments[0].entity);
    })
    .select(d => {
        return {
            Member: MemberService.getMember(d.ID),
            otherData: MemberService.dataOtherData(d.ID),
            Notes: MemberService.getNotes(d.ID),
            Log: MemberService.getLog(d.ID)
        }
    })
    .switchLatest() //Code current dies here with an object is not a function error. I believe because the return object is not an obserable. But not sure what the proper design pattern is.
    .subscribe(model => {
        //I would like that model would contain an object with the result of the 3 responses above.
        $scope.model = model;
});

person Jonathan Sheely    schedule 18.07.2014    source источник
comment
Я пропустил часть кода. все методы MemberService.get возвращают обещание var deferred = this.$http.get(ServiceUrl + '/Users/Get/' + id); return this.rx.Observable.fromPromise(deferred).map((response) => { return response.data; });   -  person Jonathan Sheely    schedule 18.07.2014


Ответы (1)


Вы можете использовать zip для синхронизации ваших запросов. zip вызовет подписку на все наблюдаемые и будет возвращаться каждый раз, когда все эти наблюдаемые срабатывают. Итак, как только будет получен nth элемент из каждого наблюдаемого, zip выдаст его nth значение, которое создается с использованием nth значений из исходных наблюдаемых.

Получив это, вы можете использовать switchLatest, который работает с Observable<Observable<T>> и гарантирует, что он всегда подписан на последние наблюдаемые данные. Таким образом, если вы выберете нового пользователя, он просто откажется от любого ожидающего запроса и вместо этого подпишется на следующий.

$rootScope.$eventToObservable('selectUser')
    .throttle(500)
    .map(data => {
        return angular.copy(data.additionalArguments[0].entity);
    })
    .map(entityToExpandedData).switchLatest()
    .subscribe(model => {
        $scope.model = model;
    });

function entityToExpandedData (entity) {
    return Rx.Observable
        .zip(
            MemberService.getMember(d.ID),
            MemberService.dataOtherData(d.ID),
            MemberService.getNotes(d.ID),
            MemberService.getLog(d.ID),
            makeExpandedData
        );
}

function makeExpandedData (member, otherData, notes, log) {
    return {
        member:     member,
        otherData:  otherData,
        notes:      notes,
        log:        log
    };
}
person cwharris    schedule 18.07.2014
comment
Спасибо, Крис, мне нравится твоя реализация. Похоже, что на самом деле возникла проблема с return angular.copy.... Я попытался заменить его простым идентификатором return 123, и я получил, что объект не является функцией из Disposable.dispose. Я скучаю по пониманию функции карты? Я могу вернуть любой объект, типа хочу правильный? Даже отдельные значения? строка, целое число и т. д. - person Jonathan Sheely; 18.07.2014
comment
В конечном итоге ваш ответ для Rx.Observable.zip() ответил на мой вопрос. Однако было 2 ошибки. Во-первых, .zip() взял ряд функций с последней перед makeExpandedData. Не массив [] запросов API. Во-вторых, основная проблема, с которой я столкнулся, заключалась в том, что rx.angular $eventToObservable по какой-то причине запускал событие dispose. - person Jonathan Sheely; 18.07.2014
comment
Ты прав! Это .zip(a,b,c,...). Интересно однако. Мне кажется, что я уже использовал .zip([a,b,c], ...) раньше... ну ладно. Можете ли вы уточнить, что вы подразумеваете под $eventToObservable, запускающим событие dispose? - person cwharris; 19.07.2014
comment
@ChristopherHarris Когда вы используете zip таким образом, объекты ответа сервера в массиве находятся в том же порядке, что и запросы? - person claireablani; 20.10.2016
comment
@claireablani switchLatest будет давать результаты только из последних наблюдаемых, поэтому порядок результатов будет сохранен, но результаты, полученные из предыдущих наблюдаемых, будут отфильтрованы. - person cwharris; 02.11.2016