简体   繁体   中英

How do I tie together 2 asynchronous request.post calls in Express and NodeJS?

I'm still learning how to make calls with using Express. Single asynchronous calls are no problem, but now I have an example where I want to feed the result of one call into the next one. My current code can be seen below, a really messy way that includes a forloop like function, a foreach and a Timeout. I'd like to learn the proper way to do this. Preferably something that scales.

The first call fills up a result object getWorkbooksResponse with a list of workbooks (incl. workbook id's and workbook names). The second part fires of a getViews call for each workbook in that list. The function checkResponse sorts through the views and puts them in alphabetical order by name.

What is the proper way to tie together 2 request.post calls? I've been looking at next(), bluebird, async,... but some examples would definitely help.

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;

With promises it would be the simplest way:

You wrap your request.post calls in

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

And then use

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM