【问题标题】:Restify.js (Connect/Express) middleware ignoring call to next() within promise callbackRestify.js (Connect/Express) 中间件在 Promise 回调中忽略对 next() 的调用
【发布时间】:2013-06-14 02:30:37
【问题描述】:

所以。在尝试为我正在构建的 Restify.js 应用程序实现一些基本中间件时,我遇到了一些怪癖,特别是 next() 和承诺回调。

用通用形式表达问题:

  var server = restify.createServer({
    name: config.name
  });

承诺解决:

  server.use(function checkAcl(req, res, next) {
    // Promise is resolved
    var promise = function () {
      var deferred = require('q').defer();
      deferred.resolve();
      return deferred.promise;
    }

    promise()
      .then(function () {
        next(); // doesn't get 'called', no response sent, connection eventually times out
      }, function () {
        res.send(new restify.NotAuthorizedError());
      });
  });
  server.use(restify.bodyParser());

  ...

承诺被拒绝

  server.use(function checkAcl(req, res, next) {
    // Promise is rejected
    var promise = function () {
      var deferred = require('q').defer();
      deferred.reject();
      return deferred.promise;
    }

    promise()
      .then(function () {
        next(); 
      }, function () {
        res.send(new restify.NotAuthorizedError()); // this works fine
      });
    }
  });

  server.use(restify.bodyParser());      

  ...

我做错了什么吗?有什么见解吗?这似乎与 promise 回调有关,它们是否以某种方式抑制了对 next() 的调用?

【问题讨论】:

  • 你的console.logs 发生了什么?
  • 好的,所以在上面的例子中。 ACL 通过(allowed === true) 所以直接回答你的问题:AuthToken Verified, Found User, ACL Passed
  • 用更通用的问题表示更新了问题(见底部)。
  • 如果用setTimeout(function () { next(); }, 0);替换promise代码会怎样?也可以尝试直接拨打next()
  • 顺便说一句,您可以用var promise = Q.resolve()var promise = Q.reject() 替换这些行,然后用promise 替换promise()

标签: node.js express connect q restify


【解决方案1】:

在自定义中间件解决问题之前添加restify.bodyParser() 中间件。

n.b:

  // Add bodyParser() to the stack before the custom middleware
  server.use(restify.bodyParser()); 

  server.use(function checkAcl(req, res, next) {
    // Promise is resolved
    var promise = function () {
      var deferred = require('q').defer();
      deferred.resolve();
      return deferred.promise;
    }

    promise()
      .then(function () {
        next(); // next() now behaves as expected.
      }, function () {
        res.send(new restify.NotAuthorizedError());
      });
  });
  ...

除此之外,我最终偶然发现this Github issue 描述了这个问题以及另一个可能的解决方案,如果你的中间件的顺序很重要(它可能确实如此)。

mcavage:很确定这实际上是在咬你的节点(因为你的数据被发送到无处)。试试这个:

  var server.createServer();
  server.pre(restify.pre.pause());
  ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2018-07-13
    • 2023-01-31
    • 2023-04-08
    • 1970-01-01
    • 2018-04-01
    • 1970-01-01
    相关资源
    最近更新 更多