如何在Express和NodeJS中将2个异步request.post调用绑定在一起?

时间:2016-08-19 10:11:57

标签: javascript node.js asynchronous

我还在学习如何使用Express拨打电话。单个异步调用没有问题,但现在我有一个例子,我想将一个调用的结果提供给下一个调用。 我现在的代码可以在下面看到,这是一个非常混乱的方式,包括类似函数,foreach和Timeout的forloop。我想学习正确的方法来做到这一点。最好是可扩展的东西。

第一个调用使用工作簿列表(包括工作簿ID和工作簿名称)填充结果对象getWorkbooksResponse。第二部分触发了对该列表中每个工作簿的getViews调用。函数checkResponse对视图进行排序,并按名称按字母顺序排列。

将2个request.post调用绑定在一起的正确方法是什么? 我一直在看next(),bluebird,async,......但是一些例子肯定会有所帮助。

var express = require('express');
var request = require('request');
var router = express.Router();

//initialize values
var workbookId = -1;

router.get('/workbooks/views', function(req, res) {
  var workgroup = req.query.workgroup;
  var authToken = req.query.auth_token;
  var serverUrl = req.query.server_url;

  //Assemble body for POST request...
  var requestedBody = {
    method: 'getWorkbooks',
    params: {
      page: {
        startIndex: 0,
        maxItems: 999
      },
      filter: {
        operator: 'and',
        clauses: []
      }
    }
  };

  //Send POST request...
  request.post({
    url: 'https://' + serverUrl + '/vizportal/api/web/v1/getWorkbooks',
    body: JSON.stringify(requestedBody),
    headers: {
      'Cookie': 'workgroup_session_id=' + workgroup + '; XSRF-TOKEN=' + authToken,
      'X-XSRF-TOKEN': authToken
    }
  }, function(err, response, body) {
    body = JSON.parse(body);
    var result = body.result;

    if (result.errors) {
      return res.json({
        http_code: 401
      });
    } else {
      getWorkbooksResponse = result;
      var getViewsWorkbooksResponse = [];

      var forloop = function(i) {
        if (i < getWorkbooksResponse.totalCount) {
          workbookId = getWorkbooksResponse.workbooks[i].id;
          var workbookName = getWorkbooksResponse.workbooks[i].name;

          request.post({
            url: 'https://' + serverUrl + '/vizportal/api/web/v1/getViews',
            body: JSON.stringify({
              method: 'getViews',
              params: {
                page: {
                  startIndex: 0,
                  maxItems: 999
                },
                filter: {
                  operator: 'and',
                  clauses: [{
                    operator: 'eq',
                    field: 'workbookId',
                    value: workbookId
                  }]
                }
              }
            }),
            headers: {
              'Cookie': 'workgroup_session_id=' + workgroup + '; XSRF-TOKEN=' + authToken,
              'X-XSRF-TOKEN': authToken
            }

          }, function(err, response, body) {
            body = JSON.parse(body);
            var result = body.result;

            if (result.errors) {
              response = {
                http_code: 401
              };
            } else {
              result.views.forEach(function(view) {
                view.workbookName = workbookName;
                getViewsWorkbooksResponse.push(view);
              });
            }
          });

          forloop(i + 1);
        } else {

          var checkResponse = function() {
            if (getViewsWorkbooksResponse) {

              //Alphabetize Response array on view name
              getViewsWorkbooksResponse.sort(function(a, b){
                return a.name.localeCompare(b.name);
              });

              return res.json({
                http_code: 200,
                response: getViewsWorkbooksResponse
              });
            }
          };
          setTimeout(checkResponse, 1000);
        }
      };

      if (getWorkbooksResponse.totalCount) {
        forloop(0);
      }
    }
  });
});

module.exports = router;

1 个答案:

答案 0 :(得分:0)

凭借承诺,这将是最简单的方式:

您将request.post调用包装在

new Promise((resolve,reject)=>
{ ... 
  request.post(...,function(err,response, body){
          if (result.errors){reject(/* error info here */)}
          else {resolve(/* data goes here */)}
          }
});

然后使用

Promise.all[promise1,...,promiseN].then(function(result){ //here is where you gonna do things after all requests are done })