Как отправить ошибку до создания наблюдаемого объекта

#javascript #angular #typescript #rxjs

#javascript #angular #typescript #rxjs

Вопрос:

Я пытался выяснить, как с этим справиться, но как вы отправляете ошибку в подписку в функции, когда наблюдаемый объект еще не создан?

Возьмем пример ниже, я создаю тему и проверяю правильность ввода. Если оно неверно, как мне создать наблюдателя и отправить ему сообщение об ошибке? С тем, что у меня есть ниже, ошибка была отправлена, но наблюдатель еще не вернулся.

 @Component({})
export class MyComponent {
  public myFunction(first: string, last: string) {
    let sub = new Subject<boolean>()
    if(first.trim().length === 0 || last.trim().length === 0) {
      sub.error(new Error('Invalid String'))
      return sub.asObservable()
    }

    this.httpClient
        .post('/endpoint', JSON.stringify({first, last}))
        .subscribe(result => sub.next(result))

    return sub.asObservable()
  }
}
  

Комментарии:

1. Я бы throw по ошибке, а затем использовал try , catch из вызывающей функции.

Ответ №1:

Обновление / исправление Stackblitz Пример

Вы можете использовать метод subject error и создать ошибку, даже если вы не подписаны на тему. и когда вы подписываетесь на него. он получит уведомление об ошибке.

Как метод error, так и метод complete отправят уведомление всем старым подписчикам, и даже если появится новый подписчик. это новое также получит эту ошибку или полное уведомление.

ваш код должен работать.

 constructor() {
  this.subjectFunction()
   .subscribe(
     response => console.log(response),
     error => console.log(error), //the control will goes here after error notification
     () => console.log('completed'))
}

subjectFunction() {
    let sub = new Subject<boolean>()
    if(first.trim().length === 0 || last.trim().length === 0) { // if this is true
      sub.error({error: 'Invalid String'})
      return sub.asObservable()
    }
    return sub;
}
// Console Output: {error: 'Invalid String'}

  

Вы также можете использовать throwError в rxjs
Создает наблюдаемый объект, который не передает наблюдателю никаких элементов и немедленно отправляет уведомление об ошибке.

 import { throwError } from 'rxjs';
//.....
return throwError({error: 'Invalid Data'});
//......
  

Старый

The below solution is for handling new emits before returning observables/subject. not for error

Существуют разные способы справиться с этим. Упоминая лишь некоторые из них. Это зависит от потребностей бизнеса.

1. Использование функции setTimeout

     if(first.trim().length === 0 || last.trim().length === 0) {
      setTimeout(() = {
        sub.next({data: 'String'})
      }, 0)
      return sub.asObservable()
    }
  

2. Использование темы воспроизведения

     let sub = new ReplaySubject(1)
    if(first.trim().length === 0 || last.trim().length === 0) {
      sub.next({data: 'String'})
      return sub.asObservable()
    }
  

** 3. Субъект поведения и AsyncSubject также могут использоваться

Комментарии:

1. Если я возвращаю два разных наблюдаемых, подписка все еще выполняется правильно? Подписка не привязана к конкретному наблюдаемому праву?

2. да !. вы можете подписаться на любой наблюдаемый объект. Единственное условие — он должен быть активен во время подписки. Также вы можете использовать AsyncSubject для вышеупомянутой вещи, как я уже сказал, есть разные способы справиться с этим.