RxJs:Web请求的序列。什么是比我更好的解决方案?

时间:2017-03-20 07:08:58

标签: rxjs rxjs5

我有一个N(整数)网址数组。我想发布网络请求。

要求

  1. 更新状态:我们开始发布网络请求
  2. 请求是一个接一个地提出
  3. 在每次网络请求之前,我们都会更新我们要拨打的网址。
  4. 更新状态:完成(收到所有网址后)
  5. 我想发出以下事件

    • 以网址开头
    • Emit:String:盯着网络请求

    循环开始(网址应该一个接一个地加载,而不是一次全部加载。数据一收到就会发出)

    • 发射:字符串:加载网址N [i]
    • Emit:Object:url N [i]
    • 的数据

    循环结束

    • 发射:字符串:完成

    以下是我的解决方案。我正在寻找更好的解决方案

    https://jsbin.com/kotizid/edit?html,js,console

    //Fake Webrequest. Returns a promise
    function fakeWebrequest(url){
        return new Promise(function(resolve){
            console.log('Making Web request for: '+url);
            setTimeout(function(){
              resolve('RESPONSE: of: '+ url);
            },500);
        });
    }
    
    
    //Urls lists
    //null added at end to indicate end. Its a hack
    let urls$ = Rx.Observable.of(['url 1','url 2',null]);
    
    
    //Status Update
    let status1$= urls$.map(()=>'Start downloading...')
    
    //Queue
    let queue$ =  urls$.flatMap((url)=>url)
                  .concatMap((url)=>{
                        if(url==null){
                            return Rx.Observable.of(null)
                        }
                        let status$= Rx.Observable.of(`Loading ${url}`);
                        let promise$= Rx.Observable.fromPromise(fakeWebrequest(url))
                        return status$.merge(promise$);
                  })
    
    let finalSeq$ = status1$.merge(queue$);
    
    
    
    finalSeq$.subscribe(function(res){
        if(res==null){
            //End
        }else{
            console.log(res);
        }    
    })
    

    我的代码出现问题

      在网址末尾添加
    1. null
    2. 订阅事件必须处理不同类型的数据,这意味着我必须添加ifs来猜测触发了哪个事件。例如,如果订阅中的res是字符串,则它必须是状态。如果它的空序列必须结束。
    3. 我正在寻找更好的解决方案。请建议。

1 个答案:

答案 0 :(得分:1)

假设我正确理解了您的问题,可能的解决方案是:

const { Observable } = Rx;

// fake http request
function fakeWebrequest(url){
    return Observable
        .of(`RESPONSE: of: ${url}`)
        .delay(500);
}


const urls = ['url 1','url 2'];

let requests$ = Observable.from(urls.map(url => fakeWebrequest(url)));

requests$
  .concatAll()
  .subscribe(
    // next
    res => {
      console.log(res)
    },
    // error
    _ => {},
    // complete
    _ => console.log('All requests ended')
  );

输出如下:

RESPONSE: of: url 1
RESPONSE: of: url 2
All requests ended

http://jsbin.com/muquzuwexa/edit?js,console