最近在进行 API Restful 改造,其间测试同学老是”质问“为什么保存一个资源而已页面响应这么慢,不是说用了SPA(Single Page Application),页面响应如丝般顺滑吗?哎,知道真相的我眼泪掉下来,只能替 SPA 说一句:“这锅我不背”。那这个黑锅该由谁来背?
应该由服务器端来背。我们已经很习惯利用 Koa 内置的关键字来处理异步请求同时避免 ”callback hell“,从而获得和同步执行代码一样的可读性,但是还具备一个鲜为人用的功能:并行加载资源。在 Koa 世界里,一切异步操作均可被视为,均可被,HTTP 请求和数据库操作自然不例外。举个例子,如下代码:
*fetchSequentially() {
constresult={};
// 可以是 http 请求或数据库操作
result.resource1=yieldthis.client.getResource1();
result.resource2=yieldthis.client.getResource2();
returnPromise.resolve(result);
}能看出来上面那段简单的代码有什么问题吗?来测量下代码执行时间吧。
*fetchSequentially() {
constresponses={};
console.time('Total costs');
console.time('Get "resource1" costs');
responses.resource1=yieldthis.client.getResource1();
console.timeEnd('Get "resource1" costs');
console.time('Get "resource2" costs');
responses.resource2=yieldthis.client.getResource2();
console.timeEnd('Get "resource2" costs');
console.timeEnd('Total costs');
returnresponses;
}执行结果:
Get "resource1" costs: 407ms
Get "resource2" costs: 376ms
Total costs: 783 ms很明显可以看出时间总和是获取两个资源时间的累加,原因是之后的代码必须等待被的资源获取完毕(成功或失败)才会继续执行。
方案
那么如何优化呢?执行结果:
Total costs: 379ms耗费时间总和等于耗费时间最长的那个。为什么会出现如此大幅度的效率提升呢?因为会对包装入对象或数组中的资源,进行并行加载,所以时间之和取二者最长的那个。重构后的代码是不是既简单易读又兼具性能 ?
总结
本文利用了对数组或对象的并发功能,将串行的请求改变为并发,当然前提是前后资源没有依赖关系。这样的优化方式,既简单又收效快,“立竿见影”,何乐而不为。If you have multiple independent asynchronous tasks, just wrap them into an array or object, then yield it!注:
浏览器端可利用将多个请求转为并行,但须是数组
如果函数是异步获取资源通常以开头
参考
http://blog.stevensanderson.com/2013/12/21/experiments-with-koa-and-javascript-generators/
领取专属 10元无门槛券
私享最新 技术干货