【问题标题】:ES6 - make multiple requests for multiple user accounts in parallelES6 - 对多个用户帐户并行发出多个请求
【发布时间】:2016-08-18 02:09:17
【问题描述】:

我正在构建一个express.js Web 应用程序,对于其中一个 API 请求,我需要同时对多个用户帐户发出多个请求并返回一个对象。
我尝试使用generatorsPromise.all,但有两个问题:

  1. 我不会为所有用户帐户并行运行。
  2. 我的代码在响应返回后结束。

这是我写的代码:

function getAccountsDetails(req, res) {
    let accounts = [ '1234567890', '7856239487'];
    let response = { accounts: [] };

    _.forEach(accounts, Promise.coroutine(function *(accountId) {
        let [ firstResponse, secondResponse, thirdResponse ] = yield Promise.all([
            firstRequest(accountId),
            secondRequest(accountId),
            thirdRequest(accountId)
        ]);

        let userObject = Object.assign(
            {},
            firstResponse,
            secondResponse,
            thirdResponse
        );

        response.accounts.push(userObject);
    }));

    res.json(response);
}

【问题讨论】:

  • firstRequest ... 函数中有什么?这些是真正的异步功能吗?也许那里有一些内部序列化。
  • 它们是返回承诺的异步函数。
  • 实际上它们都并行运行,问题是res.json 没有等待它们。 You cannot use forEach.

标签: node.js express promise ecmascript-6 generator


【解决方案1】:

_.forEach 不知道 Promise.coroutine 并且没有使用返回值。

由于您已经在使用 bluebird,您可以改用它的 promises 感知助手:

function getAccountsDetails(req, res) {
    let accounts = [ '1234567890', '7856239487'];
    let response = { accounts: [] };

    return Promise.map(accounts, (account) => Promise.props({ // wait for object
       firstResponse: firstRequest(accountId),
       secondResponse: secondRequest(accountId),
       thirdResponse: thirdRespones(accountId)         
    })).tap(r => res.json(r); // it's useful to still return the promise
}

这应该是完整的代码。

协程很棒,但它们对于同步异步内容很有用 - 在您的情况下,您实际上确实需要并发功能。

【讨论】:

  • r 会是一个对象数组吗?
  • 我认为你不应该在循环中的每个承诺上调用res.json。而是Promise.map/all(…).then(r => res.json(r), e => res.err(e))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-19
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多