15

我对基于事件的编程很陌生(使用 node.js)。我相信有些事情我只是不明白,因为有一个特殊的问题我一次又一次地遇到。

简而言之,这个问题是在处理异步性时,它似乎妨碍了你。在我的例子中,这最常体现在使用第三方库时,这些库在设计上是非阻塞的,并促进了基于回调的 API。

例如:现在我正在写一些大量使用mranney 的 node-redis 库的东西。我的程序正在抓取 RSS 提要并将结果放入 redis。我正在使用我认为是 redis 的常见策略:

  1. 抓取提要,将结果存储为具有类似feed:<feedId>:results:<timestamp>.
  2. 将最新结果的引用存储在feed:<feedId>:latest.
var redis = require("redis");
var client = redis.createClient();

var get_latest_results = 函数 (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;
        });
    });
    // 如何为这个函数指定返回值?
}

放置return latest_readingget_latest_results函数底部失败,因为 latest_reading 直到函数准备好退出后才定义。return latest_reading在调用中放置hgetall失败,因为return引用了回调,并被 忽略get_latest_results

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

4

1 回答 1

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...
});
于 2010-10-12T21:19:46.333 回答