2016-08-19 24 views
0

我仍然在學習如何使用Express進行呼叫。單一異步調用沒有問題,但現在我有一個例子,我想將一個調用的結果提供給下一個調用。 我現在的代碼可以在下面看到,這是一個非常混亂的方式,其中包括一個forloop like函數,一個foreach和一個Timeout。我想學習正確的方法來做到這一點。最好是縮放的東西。如何在Express和NodeJS中將2個異步request.post調用綁定在一起?

第一次調用用工作簿列表填充結果對象getWorkbooksResponse(包括工作簿標識和工作簿名稱)。第二部分觸發該列表中每個工作簿的getViews調用。功能checkResponse對視圖進行排序並按名稱按字母順序排列。

將2個request.post調用連接在一起的正確方法是什麼? 我一直在尋找next(),藍鳥,異步,但一些例子肯定會有所幫助。

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

?因爲如果你使用承諾那麼這很容易實現,你也可以看看js的異步庫,它有像async.series –

+0

我在前端使用promises,但後端是你看到的東西這裏。我從你的評論中得到它我需要一個額外的外部庫(使用回調或承諾)呢? –

+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 })