JavaScript异步编程1.3.5 返值与回调的混搭_JavaScript异步编程1.3.5 返值与回调的混搭试读-查字典图书网
查字典图书网
当前位置: 查字典 > 图书网 > 编程 > JavaScript异步编程 > 1.3.5 返值与回调的混搭

JavaScript异步编程——1.3.5 返值与回调的混搭

在以上两种runCalculation实现中,有时会用到返值技术。这是出于简洁的目的而随意作出的选择。下面这行代码 return callback(calculationCache[formula]); 很容易即可改写成 callback(calculationCache[formula]); return; 这是因为并没有打算使用这个返值。这是JavaScript的一种普遍做法,而且通常无害。 不过,有些函数既返回有用的值,又要取用回调。这类情况下,切记回调有可能被同步调用(返值之前),也有可能被异步调用(返值之后)。 永远不要定义一个潜在同步而返值却有可能用于回调的函数。举个例子,下面这个负责打开WebSocket 连接以连至给定服务器的函数(使用缓存技术以确保每个服务器只有一个连接)就违反了上述规则。 var webSocketCache = {}; function openWebSocket(serverAddress, callback) { var socket; if (serverAddress in webSocketCache) { socket = webSocketCache[serverAddress]; if (socket.readyState === WebSocket.OPEN) { callback(); } else { socket.onopen = _.compose(callback, socket.onopen); }; } else { socket = new WebSocket(serverAddress); webSocketCache[serverAddress] = socket; socket.onopen = callback; }; return socket; }; (这段代码依赖于Underscore.js库。_.compose定义的这个新函数既运行了callback,又运行了初始的socket.onopen回调。 ) 这段代码的问题在于,如果套接字已经缓存且打开,则会在函数返值之前就运行回调,这会使以下代码崩溃。 var socket = openWebSocket(url, function() { socket.send('Hello, server!'); }); 怎么解决呢?将回调封装在setTimeout中即可。 if (socket.readyState === WebSocket.OPEN) { setTimeout(callback, 0); } else { // ... } 这里使用延时会让人感觉是在东拼西凑,但这总比API自相矛盾要好得多。 在本节中,我们看到了一些编写异步函数的最佳实践。请勿依赖那些看似始终异步的函数,除非已经阅读其源代码。请避免使用计时器方法来等待某个会变化的东西。如果同一个函数既返值又运行回调,则请确保回调在返值之后才运行。 一次消化这些信息确实太多了一点,不过,编写好的异步函数确实是写出优秀JavaScript代码的关键所在。

展开全文

推荐文章

猜你喜欢

附近的人在看

推荐阅读

拓展阅读

《JavaScript异步编程》其他试读目录

• 第1章:深入理解JavaScript事件
• 1.1.1 现在还是将来运行
• 1.1.2 线程的阻塞
• 1.1.3 队列
• 1.2 异步函数的类型
• 1.2.1 异步的I/O函数
• 1.2.2 异步的计时函数
• 1.3 异步函数的编写
• 1.3.1 何时称函数为异步的
• 1.3.2 间或异步的函数
• 1.3.3 缓存型异步函数
• 1.3.4 异步递归与回调存储
• 1.3.5 返值与回调的混搭 [当前]
• 1.4 异步错误的处理
• 1.4.1 回调内抛出的错误
• 1.4.2 未捕获异常的处理
• 1.4.3 抛出还是不抛出
• 1.5 嵌套式回调的解嵌套
• 1.6 小结