当前位置: 首页 > Web前端 > JavaScript

Promise和Observable之间的区别

时间:2023-03-27 16:44:39 JavaScript

StackOverflow讨论:Promises和Observable之间有什么区别?投票最多的答案之一:1777次投票Promise在异步操作完成或失败时处理单个事件。注意:有支持取消操作的Promise库,但是ES6Promises目前还不支持。ObservableObservable类似于Stream(在许多语言中),允许传递零个或多个事件,其中为每个事件调用回调。通常Observable比Promise更受青睐,因为它提供了Promise特性等等。使用Observable,无论您处理0个、1个还是多个事件都无关紧要。您可以在每种情况下使用相同的API。与Promise相比,Observable还具有可取消的优势。如果不再需要对服务器的HTTP请求结果或某些其他昂贵的异步操作,可观察订阅允许取消订阅,而Promises最终会调用成功或失败回调,即使您不再需要通知或结果。Promise会立即触发,而Observable只会在您订阅时触发。这就是Observable被称为惰性的原因。Observable提供了map、forEach和reduce等运算符,它们的用法类似于数组。还有强大的运算符,如retry()或replay()等,通常非常方便。延迟执行通过在通过订阅执行可观察对象之前建立一个运算符链来允许更多的声明式编程。第二个答案:374喜欢说明。Angular使用Rx.jsObservables而不是HTTP承诺。假设您正在构建一个搜索功能,该功能应在您键入时立即显示结果。听起来很熟悉,但这项任务带来了许多挑战。我们不希望每次用户按下一个键时都访问服务器端点,如果我们这样做,服务器将被HTTP请求淹没。基本上,我们只想在用户停止输入后触发HTTP请求,而不是每次击键。对于后续请求,不要使用相同的查询参数访问搜索端点。处理乱序响应。当我们同时处理多个请求时,我们必须考虑它们以意外顺序返回的情况。想象一下,我们首先输入computer,stop,request,然后输入car,stop,request。现在我们有两个请求正在进行中。不幸的是,携带结果到计算机的请求在携带结果到汽车的请求之后返回。我们先来看看如何使用promises来实现这个需求。当然,上面提到的边缘情况都没有得到处理。wikipedia-service.ts:从'@angular/core'导入{Injectable};从'@angular/http'导入{URLSearchParams,Jsonp};@Injectable()exportclassWikipediaService{constructor(privatejsonp:Jsonp){}search(term:string){varsearch=newURLSearchParams()search.set('action','opensearch');search.set('搜索',术语);search.set('格式','json');returnthis.jsonp.get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK',{search}).toPromise().then((response)=>response.json()[1]);我们正在注入Jsonp服务,以使用给定的搜索词向WikipediaAPI发出GET请求。请注意,我们调用toPromise以从Observable获取Promise。以Promise>作为我们搜索方法的返回类型结束。app.ts的实现://检查plnkr以获取importsimport{...}from'...'的完整列表;@Component({selector:'my-app',template:`

维基百科搜索

    {{item}}
`})exportclassAppComponent{items:Array;构造函数(私人维基百科服务:维基百科服务){}搜索(术语){this.wikipediaService.search(术语)。然后(项目=>this.items=项目);}}这里也没有惊喜。我们注入我们的WikipediaService并通过搜索方法将其功能暴露给模板。该模板简单地绑定到keyup并调用search(term.value)。我们解包由WikipediaService的搜索方法返回的Promise结果,并将其作为一个简单的字符串数组公开给模板,这样我们就可以让*ngFor循环遍历它并为我们构建一个列表。Observables真正发挥作用的地方让我们改变我们的代码,而不是在每次击键时都击中端点,我们只在用户停止输入400毫秒时发送请求为了展示这种超能力,我们首先需要获得一个Observable用户输入的搜索词。我们可以利用Angular的formControl指令,而不是手动绑定到keyup事件。要使用这个指令,我们首先需要将ReactiveFormsModule导入到我们的应用程序模块中。app.ts:从'@angular/core'导入{NgModule};从'@angular/platform-b??rowser'导入{BrowserModule};从'@angular/http'导入{JsonpModule};从'@angular导入{ReactiveFormsModule}/forms';@NgModule({imports:[BrowserModule,JsonpModule,ReactiveFormsModule]declarations:[AppComponent],bootstrap:[AppComponent]})exportclassAppModule{}导入后,我们可以使用模板中的formControl并将其设置为命名为“任期”。在我们的组件中,我们从@angular/form创建一个FormControl实例,并将其作为组件上名称term下的字段公开。在幕后,term自动公开一个Observable作为我们可以订阅的属性valueChanges。现在我们有了一个Observable,获取用户输入就像在我们的Observable上调用debounceTime(400)一样简单。这将返回一个新的Observable,如果400毫秒内没有新值出现,它只会发出一个新值。导出类App{items:Array;term=newFormControl();constructor(privatewikipediaService:WikipediaService){this.term.valueChanges.debounceTime(400)//在事件中等待400毫秒暂停.distinctUntilChanged()//如果下一个搜索词与上一个搜索词相同则忽略.subscribe(term=>this.wikipediaService.search(term).then(items=>this.items=items));我们的应用程序已经显示结果的搜索词再发出一个请求会浪费资源。要实现所需的行为,我们所要做的就是在调用debounceTime(400)之后立即调用distinctUntilChanged运算符。Observable和promise的比较:更多Jerry的原创文章在这里:《王子熙》: