【问题标题】:JavaScript Design Patterns -- Dealing With Unwanted AsynchronyJavaScript 设计模式——处理不需要的异步
【发布时间】:2011-04-24 13:28:10
【问题描述】:

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

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

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

  1. 抓取提要,将结果存储为 redis 哈希,其键类似于 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_reading 放在get_latest_results 函数的底部失败,因为latest_reading 直到函数准备退出之后 才被定义。在hgetall 调用中放置return latest_reading 失败,因为return 引用回调,并被get_latest_results 忽略。

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

【问题讨论】:

    标签: javascript asynchronous node.js redis


    【解决方案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 没有为您提供语言级别的原语,如线程或协程,您需要能够同步运行异步代码(反之亦然)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多