【发布时间】:2016-07-17 15:50:11
【问题描述】:
目标:应用程序的前端允许用户从本地机器中选择文件,并将文件名发送到服务器。然后,服务器将这些文件名与位于服务器上的文件进行匹配。然后服务器将返回所有匹配文件的列表。
问题:如果您的用户选择的文件少于几百个,这会非常有用,否则会导致响应时间过长。我不想限制用户可以选择的文件数量,也不想担心前端的 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())
}
可能的解决方案:
批量处理请求。重新编写代码,以便一次仅使用 25 个文件调用配置文件服务,并在每次响应时再次使用接下来的 25 个文件调用配置文件服务。如果这是最好的解决方案,是否有一种优雅的方法可以用 observables 做到这一点?如果没有,我将使用应该可以正常工作的递归回调。
让端点立即返回通用响应,例如“文件匹配正在上传并保存到您的配置文件”。由于所有匹配的文件都保存在后端的数据库中,这将起作用,然后我可以让前端每隔一段时间查询数据库以获取匹配文件的当前列表。这看起来很难看,但我想我会把它扔在那里。
欢迎任何其他解决方案。如果能以一种优雅的方式使用 angular2/observables 处理这种类型的持久查询,那就太好了。
【问题讨论】:
-
瓶颈在哪里?定位文件的过程?还是响应的大小太大?
-
瓶颈是查找匹配文件并发送响应所需的时间。如果用户尝试匹配几千个文件,则可能需要几分钟时间。
-
如果瓶颈在文件匹配过程中,何不试试缓存、多线程等加速呢?如果响应很大,即您实际上返回了所有文件,那么我可能会尝试分页或加载更多机制?还是不接受分页?
-
你可以使用 websockets 吗?没有超时。
-
让我看看 websockets 看看这是否是一个可行的选择。 @sdfacre 谢谢你的建议,但我的目标是找到一种方法来处理较长的响应时间,而不是找到最小化响应时间的方法。我过度简化了问题以使其保持主题,但实际上查找实际上是一组复杂的数据库查询,已经进行了相当多的优化。此外,响应对象包含文件名,而不是文件本身,因此大小不是问题。
标签: javascript api http angular rxjs