2017-09-15 64 views
0

我在移植舊的Ruby腳本使用JavaScript設置功能作爲cron實例,以便將如期運行。該函數查詢我們的mysql數據庫並檢索我們產品的庫存信息,然後將請求發送給貿易伙伴api以更新其網站上的庫存。循環的NodeJS問題由於異步/同步發出

由於節點同步性我遇到的問題。我們需要將請求劃分爲每個請求1000個項目,並且我們正在發送10k個產品。問題是每個請求只發送最近的1000個項目。 while循環內的for循環在完成json請求體的構建之前向前移動。我試圖在while循環創建匿名setTimeout的功能,試圖處理它,以及創建與請求函數的對象,並傳遞變量和它塞進一個數組一旦while循環結束遍歷,但是我得到相同的結果。不知道最佳處理方式是什麼,以便每個請求都能獲得正確的一批物品。我還需要在1000個項目的每個請求之間等待3分鐘才能達到請求上限。

query.on('end',()=>{ 
        connection.release(); 
        writeArray = itemArray.slice(0), 
        alteredArray = []; 
        var csv = json2csv({data: writeArray,fields:fields}), 
        timestamp = new Date(Date.now()); 
        timestamp = timestamp.getFullYear() + '-' +(timestamp.getMonth() + 1) + '-' + timestamp.getDate()+ ' '+timestamp.getHours() +':'+timestamp.getMinutes()+':'+timestamp.getSeconds(); 
        let fpath = './public/assets/archives/opalEdiInventory-'+timestamp+'.csv'; 

        while(itemArray.length > 0){ 
         alteredArray = itemArray.splice(0,999); 
         for(let i = 0; i < alteredArray.length; i++){ 
          jsonObjectArray.push({ 
           sku: alteredArray[i]['sku'], 
           quantity: alteredArray[i]["quantity"], 
           overstockquantity: alteredArray[i]["osInv"], 
           warehouse: warehouse, 
           isdiscontinued: alteredArray[i]["disc"], 
           backorderdate: alteredArray[i]["etd"], 
           backorderavailability: alteredArray[i]["boq"] 
          }); 
         } 

         var jsonObject = { 
          login: user, 
          password: password, 
          items: jsonObjectArray 
         }; 

         postOptions.url = endpoint; 
         postOptions.body = JSON.stringify(jsonObject); 
         funcArray.push({func:function(postOptions){request(postOptions,(err,res,body)=>{if(err){console.error(err);throw err;}console.log(body);})},vars:postOptions}); 
         jsonObjectArray.length = 0; 
        } 
        var mili = 180000; 
        for(let i = 0;i < funcArray.length; i++){ 
         setTimeout(()=>{ 
          var d = JSON.parse(funcArray[i]['vars'].body); 
          console.log(d); 
          console.log('request '+ i); 
          //funcArray[i]['func'](funcArray[i]['vars']); 
         }, mili * i); 
        } 
       }); 
      }); 
+0

您能減少到[MCVE] (你甚至可能在途中發現問題。) –

+0

感謝您的澄清,我更新了代碼示例。 –

回答

0

您需要async/awaitPromise來處理節點的js異步操作。 我不知道,如果你有支持異步/等待,所以我已經嘗試了基於承諾的解決方案節點版本。

query.on('end',() => { 
 
    connection.release(); 
 
    writeArray = itemArray.slice(0), 
 
     alteredArray = []; 
 
    var csv = json2csv({ data: writeArray, fields: fields }), 
 
     timestamp = new Date(Date.now()); 
 
    timestamp = timestamp.getFullYear() + '-' + (timestamp.getMonth() + 1) + '-' + timestamp.getDate() + ' ' + timestamp.getHours() + ':' + timestamp.getMinutes() + ':' + timestamp.getSeconds(); 
 
    let fpath = './public/assets/archives/opalEdiInventory-' + timestamp + '.csv'; 
 

 
    var calls = chunk(itemArray, 1000) 
 
         .map(function(chunk) { 
 
          var renameditemsArray = chunk.map((item) => new renamedItem(item, warehouse)); 
 
          var postOptions = {}; 
 
          postOptions.url = endpoint; 
 
          postOptions.body = JSON.stringify({ 
 
           login: user, 
 
           password: password, 
 
           items: renameditemsArray 
 
          }); 
 
          return postOptions; 
 
         }); 
 
    sequenceBatch(calls, makeRequest) 
 
     .then(function() { 
 
      console.log('done'); 
 
     }) 
 
     .catch(function(err) { 
 
      console.log('failed', err) 
 
     }); 
 

 
    function sequenceBatch (calls, cb) { 
 
     var sequence = Promise.resolve(); 
 
     var count = 1; 
 
     calls.forEach(function (callOptions) { 
 
      count++; 
 
      sequence = sequence.then(()=> { 
 
       return new Promise(function (resolve, reject){ 
 
        setTimeout(function() { 
 
         try { 
 
          cb(callOptions); 
 
          resolve(`callsequence${count} done`); 
 
         } 
 
         catch(err) { 
 
          reject(`callsequence ${count} failed`); 
 
         } 
 
        }, 180000); 
 
       }); 
 
      }) 
 
     }); 
 
     return sequence; 
 
    } 
 
    function makeRequest(postOptions) { 
 
     request(postOptions, (err, res, body) => { 
 
      if (err) { 
 
       console.error(err); 
 
       throw err; 
 
      } 
 
      console.log(body) 
 
     }); 
 
    } 
 

 
    function chunk(arr, len) { 
 
     var chunks = [], 
 
      i = 0, 
 
      n = arr.length; 
 
     while (i < n) { 
 
      chunks.push(arr.slice(i, i += len)); 
 
     } 
 
     return chunks; 
 
    } 
 

 
    function renamedItem(item, warehouse) { 
 
     this.sku = item['sku'] 
 
     this.quantity = item["quantity"] 
 
     this.overstockquantity = item["osInv"] 
 
     this.warehouse = warehouse 
 
     this.isdiscontinued = item["disc"] 
 
     this.backorderdate = item["etd"] 
 
     this.backorderavailability= item["boq"] 
 
    } 
 
});

能否請您試試這個片段,讓我知道,如果它的工作原理?我無法測試它,因爲它提出了對飛。核心邏輯在sequenceBatch函數中。答案是基於另一個question,它解釋了超時和承諾如何協同工作。

0

原來這不是在所有的封閉或異步的問題,我是建設用對象的引用,而不是導致所有被鏈接到結束陣列中的同一對象REF數據淺副本請求對象。