【发布时间】:2019-06-12 10:37:17
【问题描述】:
我在 AngularJS 中处理 Promise 方面有相当多的经验,现在我正在尝试了解 Angular 中的 Observables。
我喜欢承诺处理单个异步结果 - 它们似乎非常适合这个用例 - 但 Angular 似乎热衷于将 Observables 用于所有事情,所以我现在试图最好地理解使用此模式的实践。
以下是我如何使用承诺链实现某些目标的示例。目标是:
-
MyClass.value应该总是在doSomethingAsync()为时设置 叫 - 调用者 - 在这种情况下
doSomethingElse()应该能够链接到doSomethingAsync()如果它想并且等到它完成再使用结果
export class MyClass {
private value;
public doSomethingAsync() {
return someAsyncCall()
.then(value => {
this.value = value
});
}
}
export class MyOtherClass {
public doSomethingElse() {
const myObj = new MyClass();
let myValue;
myObj
.doSomethingAsync()
.then(value => {
myValue = value
});
}
}
我正在尝试弄清楚如何使用 Observables 来做到这一点。
我可以在doSomethingAsync() 中使用.pipe() 和tap() 来捕获该值,但问题是除非doSomethingElse() 在返回的Observable 上调用subscribe(),否则这不会被执行。我不想让doSomethingAsync() 依赖于调用者接下来会做什么。
我可以在doSomethingAsync() 中调用subscribe() 来捕获该值,但之后我不再有可返回的Observable。所以我想我可能不得不这样做:
export class MyClass {
private value;
private valueSubject: Subject<any> = new Subject<any>();
public doSomethingAsync() {
someAsyncCall()
.subscribe(value => {
this.value = value;
this.valueSubject.next(value);
});
return valueSubject.asObservable();
}
}
export class MyOtherClass {
public doSomethingElse() {
const myObj = new MyClass();
let myValue;
myObj
.doSomethingAsync()
.subscribe(value => {
myValue = value
});
}
}
但这似乎过于复杂,因为我现在也必须处理 Subjects 并且有效地跟踪 2 个不同的流程。
任何人都可以提出更好的方法吗?在我看来,这似乎更容易处理承诺......?
【问题讨论】:
-
I don't want to make doSomethingAsync() dependent on what the caller does next.这正是 observables 的重点,如果你仔细想想,它实际上很有意义。如果对值不感兴趣(即没有订阅者),那么MyClass为什么要存储任何东西? -
doSomethingAsync()方法无法返回值,因为其.then块中没有 return 语句。 -
@Adam 我猜使用 promise 模式,一个方法可以同时满足 2 个范式:1)“就做吧!”和 2) “做完之后告诉我”。使用 Observables 这不再可能 - 一个方法只能真正满足一个或另一个。可能我只需要考虑一下,但现在感觉好像我失去了一些有用的东西......
-
另外 - 我有点恼火这个问题被否决了!我认为我在清楚地提出问题方面做得很好。我是否完全了解 Observable 模式/哲学是另一个问题,但这部分是问题所在。如果有人能请教我,我将不胜感激......?
-
@DanKing - 我是 Promise 的早期采用者,我觉得我很早就开始摸索它们了,但是我对 observables 的游戏迟到了,我花了一段时间才弄清楚它们的价值高于承诺,甚至它们如何真正发挥作用(其中有很多,主要的——我觉得——是我在第一条评论中指出的)。去看看他们吧。你必须考虑的其他一点是,Observables 比 Promise 更手动,你必须订阅它们(与 Promise 相同),但你也有责任在完成后取消订阅。