V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Livid
V2EX  ›  Node.js

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

  •  2
     
  •   Livid · 2014-05-06 08:55:40 +08:00 · 5231 次点击
    这是一个创建于 3858 天前的主题,其中的信息可能已经有所发展或是发生改变。
    对于 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
       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   ·   实用小工具   ·   3128 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 14:19 · PVG 22:19 · LAX 06:19 · JFK 09:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.