Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

为异步函数添加调用队列

  我们经常会对一些操作做封装,这些操作可能是异步的。对异步操作最好的封装方式当然是使用 Promise。但并不是所有时候都可以使用 Promise,很多不支持 Promise 的情况下我们依然得用回调的方式来解决。但回调毕竟是回调,如果没有经过一些优化的话性能是会踩坑的。
  对于一个异步函数,我们可能会这么定义:
var foo = function(callback) { DoAsyncSomething(callback); };   但是很多时候并不需要每次都去执行内部的一堆事情,可以缓存其结果以提高程序性能。于是可能写出这样的代码:
var foo = function(callback) { if(foo.cache) return callback(foo.cache); DoAsyncSomething(function(result) { callback(foo.cache = result); }); };   这个代码会在第一次成功调用后把结果缓存下来,当调用时先判断是否已经有缓存的结果,有则直接使用。虽然看似没什么问题,但它没考虑在首次异步事务完成前对函数的多次调用。或者更具体一点就是它是基于第一次完成后的结果,如果第一次调用就耗费了 10 秒,那么在这 10 秒内都是没有 cache 的调用。如果异步事务是一个比较费资源的操作就会造成性能的浪费。
  更好的方式是不仅要缓存结果,还要将回调函数队列化。比如:
var foo = function(callback) { if(foo.cache) return callback(foo.cache); if(foo.queue.push(callback) > 1) return; DoAsyncSomething(function(result) { foo.cache = result; foo.queue.reverse(); while(foo.queue.length) foo.queue.pop()(result); }); }; foo.queue = [];   这样就可以将后续的回调函数放入队列中,只有首次调用时候才真正处理异步事务。当然,这整个一坨东西还是比较复杂的,如果可以的话我想用装饰器来实现会更好?
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^