簡體   English   中英

node.js應用程序中的阻止功能

[英]Blocking function in node.js application

我正在創建一個node.js應用程序。 其功能之一是上傳excel文件,然后讀取它並將其內容保存在數據庫中。 問題是我是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中插入值)的循環開始,因為node.js的主線程被阻塞,直到循環已完成其工作。

使用fs.readFile從文件中讀取數據,這是異步操作,並使用async.eachLimit而不是for循環,它是非阻塞異步操作,而如果是同步操作,則為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異步文檔。

TL; DR我不知道insert_in_db方法的實際實現是什么,但它似乎是同步方法。 在這種情況下,您的代碼實際上已被該方法阻止。

但是,我認為在數據庫中編寫異步代碼並不是一個好主意,以避免與同時訪問同一記錄有關的問題。

簡而言之,如果該方法受阻,則一定有原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM