JavaScript 设计模式——处理不需要的异步
Posted
技术标签:
【中文标题】JavaScript 设计模式——处理不需要的异步【英文标题】:JavaScript Design Patterns -- Dealing With Unwanted Asynchrony 【发布时间】:2011-04-24 13:28:10 【问题描述】:我对基于事件的编程非常陌生(使用 node.js)。我相信有些事情我只是不明白,因为有一个特殊的问题我一次又一次地遇到。
简而言之,当异步性似乎妨碍您时,该问题正在处理。在我的例子中,这最常体现在使用第三方库时,这些库在设计上是非阻塞的,并促进了基于回调的 API。
例如:现在我正在写一些大量使用mranney's node-redis library 的东西。我的程序正在抓取 RSS 提要并将结果放入 redis。我正在使用我认为是 redis 的常见策略:
-
抓取提要,将结果存储为 redis 哈希,其键类似于
feed:<feedId>:results:<timestamp>
。
在feed:<feedId>:latest
下存储对最新结果的引用。
将return latest_reading
放在get_latest_results
函数的底部失败,因为latest_reading 直到函数准备退出之后 才被定义。在hgetall
调用中放置return latest_reading
失败,因为return
引用回调,并被get_latest_results
忽略。
这只是我似乎经常要写的那种情况的一个例子。也许我正试图将方钉敲入圆孔,因为我不知道更好。似乎应该有一种非骇客的方法来解决这类问题。
【问题讨论】:
【参考方案1】:您正在与异步作斗争,因为您仍在以同步范式编写函数。
在异步中,您应该将回调附加到事件。您不应该期望像get_latest_results()
这样的异步函数会得到结果,但是您应该将回调函数作为参数传递给它,以便在结果准备好时调用它。回调将对您的结果做任何需要做的事情:
var get_latest_results = function (feedId, readyCallback)
client.get('feed:' + feedId + ':latest', function (err, res)
var latest_reading_key = res.toString();
client.hgetall(latest_reading_key, function (err, res)
readyCallback(res); //--- Trigger Callback
);
);
// how do I specify a return value for this function? //--- You don't
然后你可以这样调用你的函数:
get_latest_results(1000, function (result)
//--- Do whatever needs to be done with the latest result...
);
【讨论】:
+1。学会喜欢它。 '因为 javascript 没有为您提供语言级别的原语,如线程或协程,您需要能够同步运行异步代码(反之亦然)。以上是关于JavaScript 设计模式——处理不需要的异步的主要内容,如果未能解决你的问题,请参考以下文章