代码审查:这是否遵循rxjs原则?

代码审查:这是否遵循rxjs原则?,rxjs,Rxjs,我对反应式编程非常陌生,我想通过一个简短的代码片段了解您的意见,看看我离Rx的思维方式有多远 我的目的是从一个每次最多返回500个项目的web服务中获取大约2245个项目。因此,我必须进行几个调用并连接所有结果 我将$.getJSON返回的所有承诺存储在一个数组中,然后使用forkJoin方法一起处理结果 // get the exact total number of items function getCount() { return $.get({ url: '/s

我对反应式编程非常陌生,我想通过一个简短的代码片段了解您的意见,看看我离Rx的思维方式有多远

我的目的是从一个每次最多返回500个项目的web服务中获取大约2245个项目。因此,我必须进行几个调用并连接所有结果

我将$.getJSON返回的所有承诺存储在一个数组中,然后使用forkJoin方法一起处理结果

// get the exact total number of items
function getCount() {
    return $.get({
        url: '/sites/_api/items/count',
        contentType: "application/json;odata=verbose",
        headers: { "Accept": "application/json;odata=verbose" }
    });
}

getCount().done(function (result) {
    var promises = []; // store promises
    var total = result.d.ItemCount; // total number of items
    var batch = 500; // number of items to fetch for each request
    var count = Math.ceil(total / batch); // number of request needed

    for (var i = 0; i < count; i++) {
        var skip = batch * i; // number of item already fetched
        var top = batch * (i + 1) > total ? (total % batch) : batch; // number of item to fetch
        var p = $.getJSON("/sites/_api/items?$select=" + fieldname + "&$skip=" + skip + "&$top=" + top); // get promise
        promises.push(p); // store promise in dedicated array
    }

    // join all promises and handle all results at once
    Rx.Observable.forkJoin(promises).subscribe(function (result) {
        console.log(result); //[object, object, object, object, object]
    });

});
//获取项目的确切总数
函数getCount(){
返回$.get({
url:“/sites/_api/items/count”,
contentType:“application/json;odata=verbose”,
标题:{“接受”:“应用程序/json;odata=verbose”}
});
}
getCount().done(函数(结果){
var promissions=[];//存储承诺
var total=result.d.ItemCount;//项目总数
var batch=500;//每个请求要获取的项目数
var count=Math.ceil(总计/批处理);//需要的请求数
对于(变量i=0;i总计?(总计%batch):批次;//要提取的项目数
var p=$.getJSON(“/sites/_api/items?$select=“+fieldname+”&$skip=“+skip+”&$top=“+top”);获取承诺
promises.push(p);//将promise存储在专用数组中
}
//加入所有承诺,同时处理所有结果
Rx.Observable.forkJoin(承诺).订阅(函数(结果){
console.log(结果);//[对象,对象,对象,对象,对象]
});
});
这给了我预期的结果,但我想得到你的意见,如果有任何更好的方法来做到这一点,使用Rx

------编辑--------- 我正在添加基于流概念的第一次尝试的代码。这意味着我有一个未知数量的请求问题。我将在结果出现时将其相加(请参见函数onDataReceived),并在完成时将其作为一个整体进行处理。除了我无法找到如何通知所有请求都已完成并触发可观察对象的“已完成”方法之外

var项目=[];
var-obs;
函数onDataReceived(数据){
obs.onNext(数据);
}
函数getFieldValue(fieldname、skip、top){
var uri=“/sites/_api/items?&$skip=“+skip+”&$top=“+top;
$.getJSON(uri,onDataReceived);
}
函数getCount(){
返回$.get({
url:“/sites/_api/items/count”,
contentType:“application/json;odata=verbose”,
标题:{“接受”:“应用程序/json;odata=verbose”}
});
}
obs=新接收的受试者();
订阅(
函数(值){items=items.concat(value.d);},
函数(err){console.err(err);},
函数(){console.log(“completed”+items.length);}
);
getCount().done(函数(结果){
var total=结果d.ItemCount;
var批次=500;
var计数=数学单元(总计/批次);
对于(变量i=0;i总计?(总计百分比批次)-1:批次;
getFieldValue(跳过,顶部);
}

});您的代码并没有利用Rx提供的所有功能,只是将其接口更改为可观察的。这仍然是一个内部承诺的所有方式

承诺是迫切的,因此调用
$\u json()
将立即开始获取数据。如果可能,从代码中挤出尽可能多的承诺,或者至少用
Rx.Observable.defer()将它们包装起来

尝试使您的函数返回一个懒惰的可观察值,该值仅在
开始运行时才返回。subscribe
开始运行请参见下面的示例实现,其中包括节流(10个并发请求到API以获取页面详细信息)

函数mock\u get\u count(){
返回可观测的接收值(255)
.延迟(500)
.toPromise();//模拟$.get()签名(返回承诺)
}
函数模拟获取页面(第页){
返回可观测的接收值(“”)
.do(()=>console.log('起始页'+第页))
.ignoreElements()
康卡特先生(
接收可观测范围(第10页,第10页)
.toArray()
.delay(1000+Math.random()*2000)/*缓慢的api,响应需要1-3秒*/
)
.toPromise()/*来模拟您的$.JSON()签名(返回承诺)*/
;
}
函数getAllResults(){
返回Rx.Observable.defer(()=>mock\u get\u count())
.mergeMap(itemCount=>{
const pages=Math.ceil(itemCount/10);
log('itemCount:'+itemCount+',pages:'+pages);
返回可观察的接收范围(0页)
.合并地图(
p=>Rx.Observable.defer(()=>mock\u get\u page(p)),
无效的
10/*对API的并发请求*/
);
})
}
getAllResults().subscribe(console.log)

我投票结束这个问题,因为它属于主题,谢谢你的回答。我理解延迟加载的好处,尽管这对我来说并不是一个问题,因为我无论如何都要做这些请求。我更关心的是,我有一个未知数量的请求,我需要处理结果作为一个整体,当他们全部完成。我转向RxJS,因为我真的可以看到这是一条流。我已经编辑了我的原始帖子,添加了基于流“模式”的第一次尝试的代码,但我无法发现如何注意到所有请求都已完成并触发可观察的“完成”方法……嗨,朱利安,请查看我的修订答案和你问题的Rx版本。延迟加载正是您所需要的,因为您有未知数量的请求。你需要控制这些。您仍然可以使用Rx流式传输结果。