2017-08-29 132 views
0

我有一個NodeJS程序,我有一些麻煩。NodeJS製作一個for循環異步

所以我的for循環應該起作用的方式是,它應該遍歷我的SQL數據庫中的索引,並且在for循環的每次運行中,都應該調用另一個發出GET請求的函數。

它實際上做的是它迭代了我的所有索引,然後一次/非常快地完成每個GET請求,最終讓我受限於再次進行API調用。我嘗試使用setTimeout,但它不起作用,因爲它只是迭代到下一個索引,並且值最終未定義。

也嘗試過一個回調,但它沒有改變任何東西。我試圖尋找異步,但不能真正理解我應該做的事情。也只是一個說明,實際上沒有任何返回。在我的其他功能,我只是更新我的SQL數據庫。我只需要for循環來執行每次運行的API調用,並且只有在完成後才能繼續。

function callGet() { 

    var mysql = require('mysql'); 
    var con = mysql.createConnection({ 
     host: "localhost", 
     user: "USERNAME", 
     password: "PASSWORD", 
     database: "sys" 
    }); 

    con.query("SELECT nameAlone FROM testDB", function(err, result, fields) { 

     var i; 

     for(i = 0; i < result.length; i++){ 

     var name = result[i].nameAlone; 

     var options = { 
      method: 'GET', 
      url: 'site.com', 
      qs: { 
       key: 'MYKEY', 
       page_size: 10, 
       intent: 0, 
       itemName: name 
      }, 
      headers: { 
       'postman-token': postman-token, 
       'cache-control': 'no-cache' 
      } 
     }; 
     getListing(options,result, i);     //Only being called after the for loop iterates through all of result.length 
} 
    }); 
} 

發生的事情是這樣的一個例子,讓我們說的for循環遍歷0-2和每次運行調用打印出一個名稱的函數。取而代之的

index:0, name:Chris, index:1, name:Tony, index:2, name:John 

它會打印出:

index:0, index:1, index:2, name:Chris, name:Tony, name:John 

預先感謝任何幫助。

編輯:我已經嘗試了所有答案,適用於我提出的重複問題中的問題。試圖混淆其中的一個答案,但不太確定它是否可行。

編輯2:所有的解決方案都沒有工作。

EDIT3(解決方案):如果有人想要一個很簡單的解決辦法,我發現這個包,它是非常容易設置:https://github.com/nathan818fr/async-loop

我所要做的就是創建我的索引和設置asyncLoop數組如下:

asyncLoop(indices, function (item, next) 
{ 
    var name = result[item].nameAlone; 
    var options = { 
     method: 'GET', 
     url: 'site.com', 
     qs: { 
      key: 'MYKEY', 
      page_size: 10, 
      intent: 0, 
      itemName: name 
     }, 
     headers: { 
      'postman-token': postman-token, 
      'cache-control': 'no-cache' 
     } 
    }; 

    getListing(options,result, item); 
    next(); 
}, function() 
{ 
    console.log('Finished!'); 
}); 
+0

的可能的複製[異步的JavaScript循環處理(https://stackoverflow.com/questions/9772400/javascript-async-loop-processing) – Paul

+0

用一個定時器,已經嘗試與實際延遲和setTimeout 0技巧。 – Tony

+0

@Paul你提出的問題是關於如何阻止長時間運行的任務,從佔線和捱餓其他任務。這個問題似乎是等待循環的每次迭代完成異步操作。 – apsillers

回答

0

你可以使用我的'ploop'函數的承諾。 ploop基本上接受一個返回promise的函數,函數需要的任何參數以及決定ploop是否完成的函數。你不填第四個參數。下面是直到它找到數4使用ploop繪製的隨機數的示例:

// Function that returns a promise 
var searchForNumber = function(number) { 
    return new Promise(function(resolve, reject) { 
     setTimeout(function() { 
     var min = 1; 
     var max = 10; 
     var val = Math.floor(Math.random()*(max-min+1)+min); 

     console.log('Value is: ' + val.toString());   

     return resolve(val);   
     }, 1000); 
    }); 
}; 

// fn  : function that should return a promise. 
// args : the arguments that should be passed to fn. 
// donefn : function that should check the result of the promise 
// and return true to indicate whether ploop should stop or not. 
// promise: A promise value that is used internally by ploop and should never 
// be passed in by the caller of ploop. 
var ploop = function(fn, args, donefn, promise) { 
    return (promise || Promise.resolve(true))  
     .then(function() { 
      return(fn.apply(null, args)); 
     }) 
     .then(function(result) { 
     var finished = donefn(result); 
     if(finished === true){ 
      return result; 
     } else { 
      return ploop(fn, args, donefn, promise); 
     } 
    }); 
}; 

var searchFor = 4; 

var donefn = function(result) { 
    return result == searchFor; 
}; 

console.log('Searching for: ' + searchFor); 
ploop(searchForNumber, [searchFor], donefn) 
    .then(function(val) { 
    console.log('Finally found! ' + val.toString()); 
    process.exit(0); 
    }) 
    .catch(function(err) { 
    process.exit(1); 
    }); 

一切,但ploop函數本身是示例代碼。以下是演示:

http://jsbin.com/woxetos/edit?js,console

+0

我現在就試試這個謝謝,必須移動一些代碼才能試試 – Tony

+0

當我設置了一切,我設法找到一個稍微不同的解決方案,所以我現在很好,但你帶我到解決方案,所以謝謝你:)我完成處理我的代碼後,我會給這個解決方案也試試。花了我一段時間,因爲我以前沒有處理過承諾。再次感謝 – Tony