JavaScript设计模式 - 处理不需要的异步

时间:2010-10-12 21:14:27

标签: javascript asynchronous node.js redis

我对基于事件的编程很新(使用node.js)。我相信有些东西我只是不喜欢它,因为有一个特殊的问题,我一次又一次地遇到。

简而言之,这个问题正在处理异步性,因为它似乎妨碍了你。在我的情况下,这通常表现在使用第三方库时,这些库在设计上是非阻塞的,并且可以推广基于回调的API。

例如:现在我正在写一些大量使用mranney's node-redis library的东西。我的程序正在抓取RSS提要并将结果隐藏到redis中。我正在使用我认为是re​​dis的常用策略:

  1. 抓取Feed,将结果存储为带有feed:<feedId>:results:<timestamp>之类密钥的redis哈希值。
  2. 将参考存储在feed:<feedId>:latest下的最新结果。
  3. var redis = require("redis");
    var client = redis.createClient();
    
    var get_latest_results = function (feedId) {
        client.get('feed:+ feedId + ':latest', function (err, res) {
            var latest_reading_key = res.toString();
            client.hgetall(latest_reading_key, function (err, res) {
                var latest_reading = res;
            });
        });
        // how do I specify a return value for this function?
    }
    

    return latest_reading置于get_latest_results函数的底部失败,因为在 函数准备好退出之后,才定义latest_reading。在return latest_reading调用中放置hgetall失败,因为return引用回调,get_latest_results会忽略该调用。

    这只是我似乎不断写下来的那种情况的一个例子。也许我正试图将方钉钉入圆孔,因为我不知道更好。似乎应该有一种解决这类问题的非黑客方式。

1 个答案:

答案 0 :(得分:28)

你正在努力应对异步,因为你仍然在同步范式中编写函数。

在异步中,您应该将回调附加到事件。您不应该期望来自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...
});