2017-03-16 6 views
1

node.jsアプリケーションを作成しています。その機能の1つは、Excelファイルをアップロードし、それを読み取って内容をデータベースに保存することです。問題は、私がnode.jsを初めて使用していて、ノンブロッキングコードの概念を理解できないため、この関数がメインスレッドをブロックしているように見えるので、この問題を解決するためにいくつかの助けが必要です。node.jsアプリケーションのブロック機能

app.post('/admin/upload_file', function(req, res) { 
    var sampleFile; 
    if (!req.files) { 
     res.send('No files were uploaded.'); 
     console.log('No files were uploaded.'); 
     return; 
    } 
    sampleFile = req.files.sampleFile; 
    var fileArray = sampleFile.name.split('.'); 
    var extension = fileArray[fileArray.length - 1]; 
    if (extension == "xlsx") { 
     sampleFile.mv('./public/uploads/sample_file.xlsx', function(err) { 
      if (err) { 
       res.status(500).send(err); 
      } else { 
       var entries = parsing_file(req, res); 
       if (entries.length > 0) { 
        for (var i = 0; i < entries.length; i++) { 
         // this loop on database queries block the main thread 
         model.insert_in_db(entries[0], function(rows) {}); 
        } 
       } 
       res.redirect('/admin'); 
      } 
     }); 
    } else { 
     res.redirect('/admin'); 
    } 
}); 

parsing_file関数は、ファイルを解析し、配列にオブジェクトとして値を格納する、問題は(dBでの値を挿入する必要があり)、データベースクエリにループがメインスレッドとして起動したときに起動しますloopの作業が完了するまで、node.jsはブロックされます。

答えて

1

使用fs.readFileそれは非同期操作で、ファイルからデータを読み込み、forループの代わりasync.eachLimitを使用するには、forループしながら、同期操作

fs.readFile('./public/uploads/sample_file.xlsx', function (err, data) { 
     if (err) { 
      res.status(500).send(err); 
     } else { 
      var entries = parsing_file(req, res);     
      if (entries.length > 0) { 
       async.eachLimit(entries, 10, function(entrie, callback){      
        model.insert_in_db(entrie, function(rows) {callback()}); 
       },function(err){ 
         if(err) { 
         // One of the iterations produced an error. 
         // All processing will now stop. 
         console.log('A file failed to process'); 
         } else { 
          console.log('All files have been processed 
          successfully'); 
          return res.redirect('/admin'); 
         } 
       })     
     }   
    }); 

https://caolan.github.io/async/docs.html#eachLimit非同期のドキュメントを読めば、それは非ブロッキング非同期操作です詳細については。

+0

これは、特に私が 'async.eachLimit'の部分に関して特に探しているものですが、制限数を設定するベストプラクティスは何ですか?またはクエリが実行される時間に依存しますか? – Karim

+0

async.leachLimitは、一度に最大非同期操作数を設定するために使用されます。各制限が並行して実行されるので、ループに保存するレコードが数千になると、ノードはコールスタックがいっぱいになり、エラーがスローされます。これを避けるために、制限されたレコードを並行して実行し、実行後に次のレコードを並列に実行するためにlimitを使用します。制限数はあなたのロジックに依存します。各リミット関数内で何をしているのですか? –

-2

TL; DR 私はinsert_in_dbメソッドの実際の実装が何であるかを知らないが、それは、同期方法のようです。この場合、コードは実際にそのメソッドによってブロックされます。

私の意見では、同時に同じレコードにアクセスすることに関連する問題を避けるために、非同期コードをdbに書くことは素晴らしい考えではありません。手短に言えば、その方法がブロックしている場合は、その理由が必要です。

関連する問題