【问题标题】:How to inject `resolve` into a callback?如何将`resolve`注入回调?
【发布时间】:2016-07-04 11:15:40
【问题描述】:

我想在 express 中组合中间件以使它们并行,而不是如果您将 app.use(path, /* middlewares *,/ callback) 放入顺序中。

我写了如下函数:

function makeParallelMiddleware(args) {
  let makePromises = (req, res) => args.map((func) => {
    return new Promise((resolve, reject) => {
      console.log('In promise: ' + func.name);
      func(req, res, resolve);
    })
  });
  return (req, res, next) => Promise.all(makePromises(req, res)).then(next())
}

但这似乎不能正常工作。我使用以下两个中间件进行测试:

function middlewareA(req, res, next) {
  req.A = 1;
  console.log('I am in A');
  setTimeout(() => {
    console.log('I am in A delay');
    if (req.C) {
      req.C = 'BA'
    } else {
      req.C = 'A'
    }
    next()
  }, 1000)
}

function middlewareB(req, res, next) {
  req.B = 1;
  if (req.C) {
    req.C = 'AB'
  } else {
    req.C = 'B'
  }
  next()
}

app.get('/parallel', makeParallelMiddleware([middlewareA, middlewareB]) ,(req, res) => {
  res.send(req.C);
});

当我访问/parallel时,我只能得到“B”而不是“BA”。

如何在设置req.C 之前解决promise?如何更正此问题以获得所需的结果?

【问题讨论】:

  • then(next()) 应该是then(next)
  • 如果你想走承诺路线,你应该让你的中间件返回承诺。如果由于某种原因你仍然需要回调,你不能只是传递resolve,因为失败与承诺不同。请参阅 here 如何正确地从节点样式回调中获取承诺。

标签: node.js promise closures


【解决方案1】:

改变这个:

return (req, res, next) => Promise.all(makePromises(req, res)).then(next())
//                                                   remove parens here ^^ 

到这里:

return (req, res, next) => Promise.all(makePromises(req, res)).then(function(results) {
    next();
});

您是立即调用next(),而不是传递稍后可以通过.then() 方法调用的函数引用。此外,next() 可能不喜欢将数组传递给它,而 .then() 在你的情况下会传递这样的数组,所以最好只包装一个自定义函数并调用普通的 next()


而且,如果您的任何一个 Promise 拒绝它们,如果它们抛出异常,您还需要一些错误处理。

【讨论】:

  • 我很确定next 不喜欢以数组作为第一个参数来调用。请改用.then(next.bind(null, null), next)
  • @Bergi - 是的,我想知道在这种情况下会发生什么。我已经编辑了。
猜你喜欢
  • 2016-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 2012-01-27
  • 2011-07-06
  • 1970-01-01
  • 2012-08-13
相关资源
最近更新 更多