gpt4 book ai didi

javascript - Angular2/RXJS - 处理潜在的长查询

转载 作者:太空狗 更新时间:2023-10-29 17:55:20 25 4
gpt4 key购买 nike

目标:应用程序的前端允许用户从他们的本地计算机中选择文件,并将文件名发送到服务器。然后服务器将这些文件名与位于服务器上的文件进行匹配。然后服务器将返回所有匹配文件的列表。

问题:如果您的用户选择的文件少于几百个,这会非常有效,否则会导致响应时间过长。我不想限制用户可以选择的文件数量,也不想担心前端的 http 请求超时。

到目前为止的示例代码:

//html on front-end to collect file information
<div>
<input (change)="add_files($event)" type="file" multiple>
</div>

//function called from the front-end, which then calls the profile_service add_files function
//it passes along the $event object
add_files($event){

this.profile_service.add_files($event).subscribe(
data => console.log('request returned'),
err => console.error(err),
() => //update view function
);
}

//The following two functions are in my profile_service which is dependency injected into my componenet
//formats the event object for the eventual query
add_files(event_obj){

let file_arr = [];
let file_obj = event_obj.target.files;

for(let key in file_obj){
if (file_obj.hasOwnProperty(key)){
file_arr.push(file_obj[key]['name'])
}
}

let query_obj = {files:title_arr};

return this.save_files(query_obj)
}

//here is where the actual request to the back-end is made
save_files(query_obj){

let payload = JSON.stringify(query_obj);
let headers = new Headers();

headers.append('Content-Type', 'application/json');
return this.http.post('https://some_url/api/1.0/collection',payload,{headers:headers})
.map((res:Response) => res.json())
}

可能的解决方案:

  1. 批量处理请求。重新编写代码,以便一次仅使用 25 个文件调用配置文件服务,并在每次响应时再次使用接下来的 25 个文件调用配置文件服务。如果这是最好的解决方案,是否有一种优雅的方法可以使用可观察对象来做到这一点?如果没有,我将使用应该可以正常工作的递归回调。

  2. 让端点立即返回通用响应,如“文件匹配正在上传并保存到您的个人资料”。由于所有匹配文件都保存在后端的数据库中,这会起作用,然后我可以让前端每隔一段时间查询数据库以获取当前的匹配文件列表。这看起来很难看,但我想我会把它扔在那里。

欢迎任何其他解决方案。如果能获得以优雅的方式使用 angular2/observables 处理此类持久查询的最佳实践,那就太好了。

最佳答案

我建议您将搜索的文件数量分成可管理的批处理,然后在返回结果时处理更多文件,即解决方案 #1。以下是未经测试但我认为实现此目的的相当优雅的方法:

add_files(event_obj){

let file_arr = [];
let file_obj = event_obj.target.files;

for(let key in file_obj){
if (file_obj.hasOwnProperty(key)){
file_arr.push(file_obj[key]['name'])
}
}

let self = this;
let bufferedFiles = Observable.from(file_arr)
.bufferCount(25); //Nice round number that you could play with

return bufferedFiles

//concatMap will make sure that each of your requests are not executed
//until the previous completes. Then all the data is merged into a single output
.concatMap((arr) => {

let payload = JSON.stringify({files: arr});
let headers = new Headers();
hearders.append('Content-Type', 'application/json');

//Use defer to make sure because http.post is eager
//this makes it only execute after subscription
return Observable.defer(() =>
self.post('https://some_url/api/1.0/collection',payload, {headers:headers})
}, resp => resp.json());
}

concatMap 将阻止您的服务器执行超出缓冲区大小的操作,方法是在前一个请求返回之前阻止新请求。如果您希望它们全部并行执行,您也可以使用 mergeMap,但如果我没记错的话,在这种情况下服务器似乎是资源限制。

关于javascript - Angular2/RXJS - 处理潜在的长查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36295334/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com