2015-06-19 153 views
0

我可能有点新了解承诺esp蓝鸟的基本功能。我试图完成的是一个处理批量写入250K +行到数据库的API服务器。大约需要30秒才能完成请求。我希望API服务器根据批量写入的成功返回正常或错误。当我不使用承诺时,我没有机会冒出错误,因为请求没有等待批量写入完成。但是,如果我使用承诺错误和成功正常工作。但是,直到操作完成后,服务器才会响应。简而言之,使用promise库来处理批量写入会阻塞API服务器。蓝鸟承诺阻止自然

function chunk(arr, chunkSize) { 
    var R = []; 

    for (var i=0,len=arr.length; i<len; i+=chunkSize) 
    { 
     R.push(arr.slice(i,i+chunkSize)); 
    } 
    return promise.resolve(R); 
} 


exports.add = function(req, res) { 
var PO_STD_LT_TIME = 90; //DAYS 
    Parts.sync() 
     .then(function() { 
      return Parts.destroy({ 
       where: {} 
      }); 
     }) 
     .then(function() { 
      var workbook = XLSX.readFileSync(__dirname + '/dbo_tblCPLParts_.xlsx'); 
      var sheet_name_list = workbook.SheetNames; 
      var JSON_S = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]]); 

      var size = 40000; 
      chunk(JSON_S, size).then(function(JSON_Small) { 
       promise.each(JSON_Small, function (JSON_small_){ 
        Parts.bulkCreate(JSON_small_) 
        .catch(function(err) { 
         res.json(500, { 
          Error: "Error : " + err 
         }); 
        }) 

       }).finally(ext_fns.handleResult(res,200)) 
      }) 
      }) 

} 

处理这个问题的最好方法是什么?我是否以正确的方式使用承诺?

+0

所有js都阻塞(setTimeout/interval除外)。只有主持人可以提供休息的机会 – dandavis

+0

假设任务总是花费30秒完成,但在promisifying之前,你没有意识到。 –

回答

1

这是因为你一直在调用同步行为。罪魁祸首是

var workbook = XLSX.readFileSync(__dirname + '/dbo_tblCPLParts_.xlsx'); 

你应该改用异步的fs.readFile的XLSX等价物。另外,由于您使用的蓝鸟,你可以在XLSX模块上使用promisifyAll

var Promise = require('bluebird') 
var fs = Promise.promisifyAll(/* the XLSX module */) 

,这将让你把所有的XLSX模块的承诺。

+0

谢谢你指出这一点。不幸的是,XLSX模块在内部使用fs.readfileSync。我试图转换它,但它不工作。我想我需要看看子进程和其他并行处理的东西。 –

+0

@UmaMaheshwaraa是否有xlsx模块的任何异步版本? – royhowie

+0

找到一个,但它是一个不同的库。需要看看它是否适合我的目的。 –

1

这是一个protip。

在io.js(NodeJS)中最近添加了一个同步io标志。获取最新版本并使用--trace-sync-io运行它。它会找出你所有的同步阻塞问题 - 我怀疑他们不是承诺有关。

蓝鸟 - 它没有阻塞。