我对 RxJS 很陌生,我有一个关于 RxJS ajax 请求的问题。我需要将
progressSubscriber
实现为 RxJS 的 AjaxRequest
(因为我需要从 0% 到 100% 显示进度条)。但是,从我编写的代码来看,我不太确定如何检测请求何时done,然后我们可以在请求发生时采取一些操作。
对我的浏览器进行一些检查后
console.log()
,我想我们可以从progressSubscriber
响应中检测到done状态,无论它是否具有
status
属性。因为据我所知,当它正在发出 XHR 请求时,它没有 status
属性。
有没有更好的方法来检测请求是否被视为完成(无论是成功还是错误)。
目前这是我获得 done 状态的进度(在 ES6 中):
import { Subject } from 'rxjs';
import { ajax as rxAjax } from 'rxjs/ajax';
import { merge } from 'rxjs/operators';
let form_data = new FormData();
form_data.append( 'key', 'value' );
const progressSubscriber = new Subject();
let request$ = rxAjax({
url: 'http://localhost.com/some-api',
method: 'POST',
crossDomain: true,
withCredentials: true,
body: form_data,
progressSubscriber
});
progressSubscriber
.pipe( merge(request$) )
.subscribe( data =>{
if ( data.hasOwnProperty('status') ) {
console.log('XHR is DONE');
}
});
我希望有更优雅的方法来做到这一点。也许有 2 个回调块,例如 promise
then()
,或 success & error
回调,就像 jQuery Ajax 一样。
提前致谢。
==========更新/进度==============
基于Fan Cheung的回答,我得到了启发并寻找RxJS错误和完整签名。看来我过去学过只是忘记了
subscribe()
的基础知识,它有签名:
next()
时调用的函数因此,当前的进度我最终得到以下
subscribe()
(基于上面的代码):
progressSubscriber
.pipe( merge(request$) )
.subscribe(
data =>{
if ( data.type === 'progress' ) {//Detect if it is response of Progress ( not XHR complete response )
let upload_progress = Math.floor(data.loaded / data.total * 100 );
}
if ( data.hasOwnProperty('status') ) {
//This is still the only way i can detect the request get complete
}
},
err => {
console.log( err.target.status ); //Just found that in RxJS, XHR server response is tied into `target` field
},
complete => {
console.log( complete );//Complete will just give "undefined", seem we must really detect from first callback of subscribe() by detect if it has `status field from it response
})
大家有更好的想法,请指教。谢谢。
使用
isLoading
属性进行跟踪,点击操作符至 switch
isLoading 状态
merge(progressSubscriber.pipe(tap(()=>
this.upload_progress = Math.floor(data.loaded / data.total * 100 )
),
request$.pipe(tap(res)=>{},catchError((e)=>{..})
).subscribe()
我尝试了你的代码,但无法以百分比记录进度。
相反,我收到错误 -
Error: pipe_1.pipeFromArray(...) is not a function
你可以看一下吗...
谢谢。