2017-09-15 78 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数据浅副本请求对象。