Angular 2 - Возвращать данные непосредственно из наблюдаемого

Я ударился головой об этом, пытаясь понять это, и никакая документация, которую я смог прочитать, не дала мне ответа на мой вопрос.

У меня есть служба, которая говорит напрямую с API и возвращает наблюдаемое событие, которое при обычных обстоятельствах я бы подписал и сделал то, что я хочу, с данными, однако во вторичной службе, которая использует запросы от спокойной службы, Мне нужно иметь возможность возвращать значения из запроса.

getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                res;
            },
            err => {
                console.error(err);
            }
        );
}

returnSomething() {
    return this.getSomething();
}

В приведенном выше кратком примере я хочу знать, есть ли способ вернуть res из getSomething() в returnSomething(). Если это невозможно для достижения этой цели, какова альтернатива? Я добавлю, что на _restService довольно сильно полагаются, и я действительно не хочу начинать возиться с этим.

Ответы

Ответ 1

Поскольку HTTP-вызовы и т.п. являются асинхронными, вы получаете Observable вместо возвращаемого синхронного значения. Вы должны подписаться на него, и в обратном вызове вы получите данные. Нет никакого способа обойти это.

Один вариант заключается в том, чтобы поместить вашу логику в вызов subscribe

getSomething() {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                // do something here
                res;
            },
            err => {
                console.error(err);
            }
        );
}

Но мне нравится делать обратный вызов, чтобы вводить логику извне (возможно, компонент, возможно, другую службу):

getSomething(callback: (data) => void) {
    return this._restService.addRequest('object', 'method').run()
        .subscribe(
            res => {
                callback(res);
            },
            err => {
                console.error(err);
            }
        );
}

И в вашем компоненте или где угодно:

this._yourService.getSomething((data) => {
    // do something here
    console.log(data);
});

Ответ 2

Я не использовал это сам, но я считаю, что он должен работать в теории (:

// service.ts
getSomething() {
  let subject: Subject = new Subject();
  this._restService.addRequest('object', 'method').run()
    .subscribe(subject);
  return subject;
}

// this can be removed (;
returnSomething() {
  return this.getSomething();
}

// component.ts
ngOnInit() {
  this.service.returnSomething()
    .subscribe(res => console.log(res), err => console.log(err));
}

Для получения дополнительной информации просмотрите тематические документы. Вы можете использовать разные типы объектов, например BehaviorSubject имеет свойство value, доступ к которому вы можете получить...

ngOnInit() {
  // if you use BehaviorSubject
  this.service.returnSomething().value
}

Здесь рабочий плункер...