【问题标题】:How to use deferrable to execute a sequence of Redis operations?如何使用 deferable 执行一系列 Redis 操作?
【发布时间】:2013-10-19 18:08:43
【问题描述】:

我有以下操作使用 node_redis 创建用户:

server.post('/create_user', function(req, res, next) { 控制台.log(req.body); var body = req.body; client.hincrby('users', 'count', 1, function(err, id) { client.hmset('用户:'+id, '用户名',body.username, '密码', body.password, '电子邮件',body.email,函数(错误,写){ client.hmget('user:'+id, 'username', 'email', function(err, read) { res.send({id: id, username: read[0], email: read[1]}); }); }); }); })

我想在这里阅读有关 Deferrable 和 Promises 的内容:http://blog.jcoglan.com/2011/03/11/promises-are-the-monad-of-asynchronous-programming/

如何使用 Deferables 和 Promises 重写此代码,从而实现更清晰的异常处理以及更好的流程维护?

动作基本上是:

  1. 增加计数器以获取 ID
  2. 使用 ID 设置用户的 Redis 哈希
  3. 从 Redis 返回创建的用户

【问题讨论】:

    标签: javascript node.js redis promise


    【解决方案1】:

    有了你可以做的承诺:

    var Promise = require("bluebird");
    //assume client is a redisClient
    Promise.promisifyAll(client);
    
    server.post('/create_user', function(req, res, next) {
        console.log(req.body);
        var body = req.body;
        client.hincrbyAsync('users', 'count', 1).then(function(id){
            return client.hmsetAsync(
                'user:' + id,
                'username', body.username,
                'password', body.password,
                'email', body.email
            );
        }).then(function(write){
            return client.hmgetAsync('user:'+id, 'username', 'email');
        }).then(function(read) {
            res.send({id: id, username: read[0], email: read[1]});
        }).catch(function(err){
            res.writeHead(500);
            res.end();
            console.log(err);
        });
    });
    

    这不仅比瀑布式执行得更好,而且如果您有同步异常,您的进程不会崩溃,甚至是同步的 异常变成了承诺拒绝。虽然我很确定上面的代码不会抛出任何这样的异常:-)

    【讨论】:

      【解决方案2】:

      我已经成为异步库的粉丝。它的性能非常好,并且具有出色的可读性清理方法。

      这是使用异步瀑布函数重写的示例。

      瀑布的基本设置是:

      async.waterfal([函数数组], finalFunction);

      注意:瀑布方法期望回调函数总是有第一个参数是错误的。这样做的好处是,如果在任何步骤返回错误,它会直接带着错误进入完成函数。

      var async = require('async');
      
      server.post('/create_user', function(req, res, next) {
        console.log(req.body);
        var body = req.body,
            userId;
      
        async.waterfall([
          function(cb) {
            // Incriment
            client.hincrby('users', 'count', 1, cb);
          },
          function(id, cb) {
            // Higher Scope a userId variable for access later.
            userId = id;
            // Set
            client.hmset('user:'+id, 
              'username', body.username, 
              'password', body.password, 
              'email', body.email, 
              cb);
          },
          function(write, cb) {
            // Get call.
            client.hmget('user:'+userId, 'username', 'email', cb);
          }
        ], function(err,read){
            if (err) {
              // If using express:
              res.render('500', { error: err });
              // else
              res.writeHead(500);
              res.end();
              console.log(err);
              return;
            }
            res.send({id: userId, username: read[0], email: read[1]});
        })
      })
      

      【讨论】:

        猜你喜欢
        • 2020-09-11
        • 2019-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多