我写了很多看起来像这样的模块:
function get(index, callback) {
if (cache[index] === null) {
request(index, callback); // Queries database to get data.
} else {
callback(cache[index]);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:它是我实际代码的简化版本.
该回调要么在同一个执行中调用,要么在稍后的某个时间调用.这意味着模块的用户不确定首先运行哪个代码.
我的观察是这样的模块重新引入了多线程的一些问题,这些问题以前是由JavaScript引擎解决的.
问题:我应该使用process.nextTick
或确保在模块外部调用回调是安全的吗?
lan*_*nzz 12
这完全取决于你在回调函数中做了什么.如果你需要确保回调时回调还没有被触发get
,你将需要process.nextTick
流程; 在很多情况下,你不关心回调何时触发,所以你不需要延迟它的执行.无法给出适用于所有情况的确定答案; 始终将回调推迟到下一个滴答应该是安全的,但这种方式的效率可能会低一些,所以这是一个权衡.
我能想到的唯一情况就是你需要在下一次打勾时推迟回调,如果你真的需要在调用之后get
但在调用之前为它设置一些东西callback
.这可能是一种罕见的情况,也可能表明需要改进实际控制流程; 你应该完全依赖于何时调用你的回调,因此它所使用的任何环境都应该在get
被调用的点设置.
在基于事件的控制流中存在某些情况(与基于回调的情况相反),您可能需要推迟实际的事件触发.例如:
function doSomething() {
var emitter = new EventEmitter();
cached = findCachedResultSomehow();
if (cached) {
process.nextTick(function() {
emitter.emit('done', cached);
});
} else {
asyncGetResult(function(result) {
emitter.emit('done', result);
});
}
return emitter;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您将需要推迟缓存值的情况下,EMIT,否则该事件将调用者之前发出doSomething
不得不附加一个听众的机会.使用回调时,通常不会考虑这一点.
http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony
如果您在内部进行回调,请选择适合的方式
如果您正在创建其他人使用的模块,则异步回调应该始终是异步的.
归档时间: |
|
查看次数: |
5252 次 |
最近记录: |