请教一个 Node.js 的代码组织问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Livid
56.4D
450.54D
V2EX    Node.js

请教一个 Node.js 的代码组织问题

  •  2
     
  •   Livid
    PRO
    2014-05-06 08:55:40 +08:00 5667 次点击
    这是一个创建于 4176 天前的主题,其中的信息可能已经有所发展或是发生改变。
    对于 cache key A,如果在 redis ( https://www.npmjs.org/package/redis ) 中不存在,就通过 request ( https://www.npmjs.org/package/request ) 去某个 http 地址拿一个 json,然后如果这个 request 的 status_code 是 200 就将这个 JSON 以 cache key A 存入 redis。

    如果 cache key A 存在,就取出来,通过 JSON.parse() 还原为对象。

    然后代码继续,根据( 从 redis 里拿到的数据 或者 从 request 里拿到的数据 )执行下一步操作。

    因为 Node.js 在 redis 和 request 这里都是异步 callback,我比较好奇像这样的情况在 Node.js 中最好的做法是?
    26 条回复    2014-05-10 13:36:17 +08:00
    Livid
        1
    Livid  
    MOD
    OP
    PRO
       2014-05-06 08:59:18 +08:00
    我也想 Google,但是这个自动联想好像哪里怪怪的…

    jybox
        2
    jybox  
       2014-05-06 09:00:30 +08:00   1
    getCache = (name, setter, callback) ->
    memcached.get name, (err, result) ->
    if result
    callback result
    else
    setter (result) ->
    memcached.set name, result, ->
    callback result
    jybox
        3
    jybox  
       2014-05-06 09:01:05 +08:00   1
    ine181x
        4
    ine181x  
       2014-05-06 09:05:31 +08:00 via iPhone   1
    Xe0n0
        5
    Xe0n0  
       2014-05-06 09:05:59 +08:00   1
    refresh
        6
    refresh  
       2014-05-06 09:08:30 +08:00   1
    async, Q, promise
    vfasky
        7
    vfasky  
       2014-05-06 09:08:48 +08:00   1
    windjs 可以做到 python 的 yield http://windjs.org/cn/docs/async/method.html

    但很多人不喜欢 eval, 其实 windjs 是可以像 coffee 一样预编译的。 但是 windc 一直没进度。

    老赵可能放弃了。 可惜啊!

    ECMAScript 6 看来短期不会成熟
    mytharcher
        8
    mytharcher  
       2014-05-06 09:09:13 +08:00   1
    用Promise,async queue,或者直接ES6的yeild
    mytharcher
        9
    mytharcher  
       2014-05-06 09:10:53 +08:00
    不好意思,拼错了,是yield
    chone
        10
    chone  
       2014-05-06 09:13:30 +08:00 via Android
    Promise A+ 应该是最适用的。
    Xe0n0
        11
    Xe0n0  
       2014-05-06 09:14:58 +08:00
    如果使用 Promise,结果应该类似

    http.get(url).then(function(data){

    if (A in data) return data[A];
    else reject("key A not exists");

    }).then(JSON.parse).then(function(object){
    ...
    }).catch(function(error_code){
    ...
    });

    可以写成 chain 的形式,这里把可能的错误都 catch 了,如果不需要可以写得更短。
    NemoAlex
        12
    NemoAlex  
       2014-05-06 09:34:11 +08:00
    没有什么好办法,用 callback 的形式就是这么憋屈,用 promise 好看一点,也没好到哪去
    rannnn
        13
    rannnn  
       2014-05-06 09:50:06 +08:00
    我用 flow.js 完成后call this就会进行下一个function

    flow.exec(
    function() {
    setTimeout(this, 200);

    },function() {
    setTimeout(this, 200);

    },function() {
    // done

    }
    );
    est
        14
    est  
       2014-05-06 10:08:42 +08:00   1
    最近学习到的 require('events').EventEmitter 姿势



    http://blog.est.im/post/84684285685
    WildCat
        15
    WildCat  
       2014-05-06 10:21:36 +08:00 via iPhone
    借贴提问,
    Eventproxy, Async, Promise的用途是否类似?
    lloydsheng
        16
    lloydsheng  
       2014-05-06 10:34:21 +08:00
    消除callback最流行的方法 https://www.npmjs.org/package/q
    j
        17
    j  
       2014-05-06 10:37:18 +08:00
    支持 @Xe0n0 的方法,
    有个小建议是为了将来自己维护方便。还是给匿名函数起个合理的名字比较好。
    luin
        18
    luin  
       2014-05-06 10:39:57 +08:00
    这种简单的逻辑最好直接用 @jybox 的方法,不要用 async, yield 甚至 windjs。Promise 也要视情况使用,否则反而会影响代码可读性。

    另外 @jybox 的代码还可以优化的点是在 if 语句中使用 return 尽快退出条件判断,以免去 else 那层的嵌套。
    aisk
        19
    aisk  
       2014-05-06 10:56:30 +08:00
    chemzqm
        20
    chemzqm  
       2014-05-06 11:05:09 +08:00   1
    @vfasky 作者感受到 co https://github.com/visionmedia/co 的强大之后不再开发了,这是我见过最优雅的异步实现方式,没有 node 0.11 可以使用 regenerator https://github.com/facebook/regenerator
    cfddream
        21
    cfddream  
       2014-05-06 11:09:46 +08:00
    楼上都把几种常用姿势说了,选择自己喜欢的、统一、好维护的风格。
    bear
        22
    bear  
       2014-05-06 11:18:59 +08:00
    感觉Promise方式好像解决不了楼主的问题,它每次都会发出请求,而楼主是希望当内存里有,就不去请求,难道是我对Promise理解有误?
    virushuo
        23
    virushuo  
       2014-05-06 12:09:14 +08:00
    callback或者 promise https://www.promisejs.org
    cfddream
        24
    cfddream  
       2014-05-06 13:31:11 +08:00
    https://github.com/petkaantonov/bluebird 注重性能可以试试这个
    arzusyume
        25
    arzusyume  
       2014-05-07 09:23:34 +08:00
    @bear 我觉得可以呀,拿when举例

    deferred = when.defer();
    if (cache) {
    process.nextTick(function() {deferred.resolve(cache);});
    } else {
    loadCache(function(err, data) {deferred.resolve(data);});
    }
    return deferred.promise;
    rekey
        26
    rekey  
       2014-05-10 13:36:17 +08:00
    @arzusyume 如果cache取不到就直接返回一个request的promise给业务方啊。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     843 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 34ms UTC 20:44 PVG 04:44 LAX 13:44 JFK 16:44
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86