间或异步的函数有一个常见变种是可缓存结果的异步请求类函数。举例来说,假设正在编写一个基于浏览器的计算器,它使用了网页Worker对象以单独开一个线程来进行计算。(第5章将介绍网页Worker对象的API。)主脚本看起来像这样: var calculationCache = {}, calculationCallbacks = {}, mathWorker = new Worker('calculator.js'); mathWorker.addEventListener('message', function(e) { var message = e.data; calculationCache[message.formula] = message.result; calculationCallbacks[message.formula](message.result); }); function runCalculation(formula, callback) { if (formula in calculationCache) { return callback(calculationCache[formula]); }; if (formula in calculationCallbacks) { return setTimeout(function() { runCalculation(formula, callback); }, 0); }; mathWorker.postMessage(formula); calculationCallbacks[formula] = callback; } 在这里,当结果已经缓存时,runCalculation函数是同步的,否则就是异步的。存在3种可能的情景。 公式已经计算完成,于是结果位于calculationCache中。这种情况下,runCalculation是同步的。 公式已经发送给Worker对象,但尚未收到结果。这种情况下,runCalculation设定了一个延时以便再次调用自身;重复这一过程直到结果位于calculationCache中为止。 公式尚未发送给Worker对象。这种情况下,将会从Worker对象的'message'事件监听器激活回调。 请注意,在第2种和第3种情景中,我们按照两种不同的方式来等待任务的完成。这个例子写成这样,就是为了演示依据哪几种常见方式来等待某些东西发生改变(如缓存型计算公式的值)。是不是应该倾向于其中某种方式呢?我们接着往下看。