2015-03-19 55 views
0

我想在node.js中执行一些异步功能,以同步执行。我正在使用async.series。以下是我的代码:node.js,异步,restify:无法使restify调用内同步async.series

async.series([ 
     function(callback){ 
      fs.truncateSync('rooms.txt', 0); 
      console.log("function1 done"); 
      callback(null, 'one'); 
     }, 
     function(callback){ 
      fs.truncateSync('sids.txt', 0); 
      console.log("start loop"); 
      var count = 0; 
      async.whilst(
       function() { return count <5 }, 
       function (callback) { 
        count++; 
        sid.generateSIDs; //---> PROBLEM!! 
        callback(); 
       }, 
       function (err) { 
       } 
      ); 
      var sids = fs.readFileSync('sids.txt').toString().split('\r\n'); 
      console.log("function2 done"); 
      callback(null, 'two'); 
     }, 
     function(callback){ 
      //lots of asynchronous callbacks 
      callback(null, 'three'); 
     } 
    ], 
    function(err, results){ 
     // results is now equal to ['one', 'two', 'three'] 
    }); 

在上面的代码中,所有内容都按预期工作(按顺序)。但是,当我添加标记为'问题'的线时,所有事情都要进行折腾! generateSIDs是一个名为sid.js的外部node.js文件中的函数。它使用restify异步发布几个HTTP GET。这里是内部sid.js代码:

'use strict'; 

var requestify = require('requestify'); 
var fs = require('fs'); 
var response = ""; 
var sessionId=""; 

function generateSIDs() { 
    //Request 1: Send Protocol Upgrade Request 
    response = ""; 
    sessionId=""; 
      requestify.request('http://url.com', { 
       method: 'GET', 
       headers: { 
        'Host': 'given', 
        'Connection': 'keep-alive', 
        'Origin': 'given', 
        'Referer': 'given' 
       }, 
       cookies: { 
        'Cookie': 'given' 
       }, 
       dataType: 'json'   
      }) 
      .then(function(response) { 
       // get the response body 
       response = response.getBody(); 
       sessionId = "extracted from response"; 

       //Request 2: Set up the session 
       requestify.request('url.com'+sessionId, { 
        method: 'GET', 
        headers: { 
         'Host': 'given', 
         'Connection': 'keep-alive', 
         'Origin': 'given', 
         'Referer': 'given' 
        }, 
        cookies: { 
         'Cookie': 'given' 
        }, 
        dataType: 'json'   
       }) 
       .then(function(response) { 
        fs.appendFile('sids.txt', sessionId+'\r\n', function (err) { 
         if (err) return console.tag("SERVER").log("file not opening: "+err); 
        }); 
        console.log("file write done"); 
       });    
      }); 
}; 
exports.generateSIDs = generateSIDs(); 

async.series()内,generateSIDs()获取调用一次,产生新的SID,然后它没有进一步的迭代。从console.log()我可以看出,由于restify调用的异步性质,只要sid.generateSIDs()被调用,即使在该函数的一次迭代完成之前,async.series()中的第三个function(callback)也会被触发。

但是,我希望sid.generateSIDs()按照while循环计数顺序运行多次。这些运行完成后,只有第三个函数(回调函数)才能执行。正如你可以从generateSIDs()了解的代码,我想在调用第三个函数之前创建多个唯一的sid。

当我使用node sid.js与命令行(不在循环中)分开运行sid.js时,它每次都运行良好并为我创建一个新的sid。

我是node.js的新手,在同一代码中处理同步和异步函数,弄乱了我的逻辑!你能帮我吗?

+0

'exports.generateSIDs = generateSIDs()'表示仅在'require'期间调用一次。从来没有别的。你打算怎么做? – slebetman 2015-03-19 03:17:48

+0

哦!是吗?那么,在标记为PROBLEM的行中,它不会一次又一次地被调用?每次运行generateSIDs()都会为我创建一个新的sid。在async.whilst()循环中,我想多次调用这个函数,比如说5次,这样连续调用generateSIDs()的5次函数将为我创建5个新的独特的sid。 – kajarigd 2015-03-19 03:20:48

+0

正确。每次调用'generateSID'时都会创建新的sid。但是,您只能调用一次。在JavaScript中,向函数中添加'()'会调用它。你只能在你的代码中做一次。 – slebetman 2015-03-19 04:04:32

回答

0

我找到了一个可行的解决方案!我从async.whilst()循环中删除了sid.generateSIDs()的执行async.series([])。相反,我在sid.js里面加入了async.whilst(),本地的lobal变量。并做了几个g现在,这是按预期工作!这是我更新的代码:

更新后的代码里面async.series

}, 
     function(callback){ 
      fs.truncateSync('sids.txt', 0); 
      console.log("start loop"); 
      var count = 0; 
      async.whilst(
       function() { return count <5 }, 
       function (callback) { 
        count++; 
        sid.generateSIDs(num); //---> FIXED! 
        callback(); 
       }, 
       function (err) { 
       } 
      ); 
      console.log("function2 done"); 
      callback(null, 'two'); 
     }, 

更新sid.js:

'use strict'; 

var requestify = require('requestify'); 
var fs = require('fs'); 

function genEachSIDs() { 
    //Request 1: Send Protocol Upgrade Request 
    var response = ""; //NOTE! I made this var local from global 
    var sessionId=""; //NOTE! I made this var local from global to avoid override of values from one instance by another 

    //code inside requestify.request(below is exactly same as given in the question above. 
    requestify.request(
     //same code as above 
    ); 
} 
// adding the while loop here! 
module.exports generateSIDs = function generateSIDs(num){ 
     var count=0; 
     async.whilst(
      function() { return count <num; }, 
      function (callback) { 
       count++; 
       genEachSIDs(); 
       callback(); 
      }, 
      function (err) { 
      } 
     ); 
    } 

我删除了行:var sids = fs.readFileSync('sids.txt').toString().split('\r\n');从第2个功能,因为这需要再次等到所有sid创建完成。