JavaScript的设计模式 - 处理不需要的不同步 [英] JavaScript Design Patterns -- Dealing With Unwanted Asynchrony

查看:112
本文介绍了JavaScript的设计模式 - 处理不需要的不同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是(如何使用Node.js)pretty新基于事件的编程。我相信,有什么东西,我只是不所著的Grokking它,因为有我保持一次又一次又一次地跨越一个特别的问题。

总之,这个问题是处理异步性时,它似乎是在用自己的方式越来越。这种情况最常表现出来,在我的情况下,第三方库,这是无阻塞设计和推广基于回调的API。工作时

例如:现在我正在写一些东西,使得大量使用 mranney的节点Redis的库的。我的计划是刮RSS源,结果塞进Redis的。我使用的是什么,我相信是Redis的一个共同战略:


  1. 刮饲料,结果存储作为一个Redis的哈希像的一些关键饲料:结果:其中p; feedId过夜。其中p时间戳>

  2. 商店参照最新的结果提要:其中,feedId>:最新


VAR = Redis的要求(Redis的);
变种客户= redis.createClient();VAR get_latest_results =功能(feedId){
    client.get('进料:+ feedId +:最新的,函数(ERR,RES){
        变种latest_reading_key = res.toString();
        client.hgetall(latest_reading_key,函数(ERR,RES){
            VAR latest_reading =资源;
        });
    });
    //我怎么指定该函数的返回值?
}

配售收益latest_reading get_latest_results 函数的底部将会失败,因为latest_reading没有定义,直到的功能是准备退出。配售 hgetall 通话中收益latest_reading 失败,因为收益指回调,并且由 get_latest_results 忽略。

这仅仅是一个什么样的情况,我似乎不断地写我的方式进入的一个例子。也许我试图砸向方钉进圆洞,因为我不知道任何好转。它似乎应该有解决这一类的问题的非hackish的方式


解决方案

您与异步挣扎,因为你仍然在同步模式编写的函数。

在异步应该高度回调的事件。你不应该从像 get_latest_results()异步函数期望的结果,但你应该把它传递一个回调函数,当结果准备好被调用的参数。回调将做任何需要用结果来完成:

  VAR get_latest_results =功能(feedId,readyCallback){
    client.get('饲料:'+ feedId +:最新的,函数(ERR,RES){
        变种latest_reading_key = res.toString();
        client.hgetall(latest_reading_key,函数(ERR,RES){
            readyCallback(RES); // ---触发回调
        });
    });
    //我怎么指定该函数的返回值? // ---你不
}

然后,你可以调用你的函数是这样的:

  get_latest_results(1000,功能(结果){
   // ---做任何需要与最新的结果完成了...
});

I'm pretty new to event-based programming (using node.js). I believe that there's something I'm just not grokking about it, because there's a particular problem that I keep coming across again and again and again.

In short, that problem is dealing with asynchronicity when it seems to be getting in your way. This most often manifests itself, in my case, when working with third-party libraries, which are non-blocking by design and promote a callback-based API.

For instance: Right now I'm writing some stuff that makes heavy use of mranney's node-redis library. My program is scraping RSS feeds and tucking the results into redis. I'm using what I believe is a common strategy with redis:

  1. Scrape feed, store results as a redis hash with a key of something like feed:<feedId>:results:<timestamp>.
  2. Store reference to the latest result under feed:<feedId>:latest.

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?
}

Placing return latest_reading at the bottom of the get_latest_results function fails, because latest_reading isn't defined until after the function is ready to exit. Placing return latest_reading within the hgetall call fails because the return refers to the callback, and is ignored by get_latest_results.

This is just one example of the kind of situation I seem constantly to write my way into. Maybe I'm trying to pound the square peg into the round hole because I don't know any better. It does seem that there should be a non-hackish way of solving this class of problems.

解决方案

You are struggling with asynchrony because you are still writing your functions in a synchronous paradigm.

In asynchrony you should attach callbacks to events. You shouldn't expect a result from an asynchronous function like get_latest_results(), but you should pass it a callback function as an argument to be invoked when the results are ready. The callback will do whatever needs to be done with your 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
}

Then you can call your function like this:

get_latest_results(1000, function (result) {
   //--- Do whatever needs to be done with the latest result...
});

这篇关于JavaScript的设计模式 - 处理不需要的不同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆