简体   繁体   English

Promise不会等待传递给下一个函数

[英]Promise doesn't wait before passing to next function

I am trying to insert all transactions into a database after I've parsed them. 解析完所有交易后,我尝试将它们插入数据库中。 I have a function called load.newload(transactionlist); 我有一个名为load.newload(transactionlist)的函数; which is passed after baby parse finishes parsing. 婴儿解析完成后通过。

I've tested my code, and it loads all the files if the file list is short, but once it gets long (around 10 files or more), it calls the load.newload(transactionlist) function even before it finished parsing. 我已经测试了我的代码,如果文件列表很短,它将加载所有文件,但是一旦它变长(大约10个文件或更多),它甚至会在解析完成之前调用load.newload(transactionlist)函数。

I was thinking maybe I should have another promise for the baby.parse function, but it doesn't seem to work. 我当时在想,也许我应该对baby.parse函数有一个新的承诺,但是它似乎不起作用。

Results look like this: 结果如下:

parse file1, parse file2, parse file3, SQL connected, Insert data successful, parse file4, parse file5 解析文件1,解析文件2,解析文件3,SQL连接,成功插入数据,解析文件4,解析文件5

How can I fix this? 我怎样才能解决这个问题?

This is my code: 这是我的代码:

var baby = require('babyparse');
var read = require('read-file');
var Promise = require('promise');
var load = require('../sql/insert');
var transactionlist = [];
var incomingfile = function(file){
     //async load file and then parse after loading
        var promise = new Promise(function (resolve, reject) {
              read( file, 'utf8', function (err, res){
              if (err) 
                {reject(err);
                console.log('Oops, an error occured while parsing the data: %s', err);}
              else {resolve(res);
                    console.log(file);}
            });
        }).then(function (results){
                var promise = new Promise(function (resolve, reject) {
                baby.parse(results , {
                    dynamicTyping: true,
                    delimiter: "|",
                    complete: function (results, error) {
                        if(error)
                        {console.log('Something went wrong');
                         reject(error);}
                        else {
                              for(i = 1; i < results.data.length - 1; i++)
                                {
                                    var transaction  = {
                                        column1 : results.data[i][14].substring(0, 6),
                                        column2: results.data[i][2].split(' ').join(''),
                                        column3: results.data[i][14].split(' ').join(''),
                                        column4: results.data[i][8],
                                        column5: results.data[i][9]
                                    }
                                    transactionlist.push(transaction);
                                }//end for loop
                                resolve(results);
                                }
                        //console.log("Finished:", JSON.stringify(results.data));
                    }//end baby parse complete:function
                    });//end baby parse function
                }).then(function (results){
                    load.newload(transactionlist);
            });//end inner .then function
        });//end .then function
}//end incoming file function


exports.incomingfile = incomingfile;


//newload function in insert.js
const sql = require('mssql/msnodesqlv8');
var config = require('../connect');
var newload = function (transactionlist){
            sql.connect(config)
              .then(() => {
                console.log('connected');
                    const table = new sql.Table('settlement');
                    table.create = true;
                    //table.columns.add('transactionid', sql.Int, { nullable: false, primary: true});
                    table.columns.add('colum1', sql.VarChar(6), { nullable: false });
                    table.columns.add('column2', sql.VarChar(50), { nullable: false });
                    table.columns.add('column3', sql.VarChar(50), { nullable: false });
                    table.columns.add('column4', sql.VarChar(50), { nullable: false });
                    table.columns.add('column5', sql.VarChar(5), { nullable: false });

                     //add here rows to insert into the table
                    for (i = 0; i < transactionlist.length; i++) {

                        table.rows.add(transactionlist[i].column1, transactionlist[i].column2, transactionlist[i].column3, transactionlist[i].column4, transactionlist[i].column5);
                        console.log('transaction list', i , JSON.stringify(transactionlist.length));
                      }     
                const request = new sql.Request();
                console.log('Ready to insert data');
                request.bulk(table, function (error, results){
                    if(error)
                    {
                        console.log('Something went wrong while inserting the data into the database');
                        sql.close();
                    }
                    else {
                        console.log('Data has been inserted successfully');
                        sql.close();
                    }
                })  
              });
};

exports.newload = newload;

The problem could be due to using a global variable transactionlist to share data among promises. 问题可能是由于使用全局变量transactionlist在承诺之间共享数据。 Given its a case of chained promises, a better way to handle data transactionlist could be to pass it along with return statement and let the next promise handle it without ambiguity (that it was updated or not). 考虑到它的链式承诺的情况,处理数据transactionlist的更好方法可能是将其与return语句一起传递,并让下一个承诺无歧义地处理它(是否已更新)。

This is how I'd do a chained promise. 这就是我做出连锁承诺的方式。

var baby = require('babyparse');
var read = require('read-file');
var Promise = require('promise');
var load = require('../sql/insert');
// var transactionlist = [];
var incomingfile = function(file){
     //async load file and then parse after loading
        var promise = new Promise(function (resolve, reject) {
              read( file, 'utf8', function (err, res){
              if (err) 
                {
                    reject(err);
                    console.log('Oops, an error occured while parsing the data: %s', err);
                }
              else {
                    resolve(res);
                    console.log(file);
               }
            });
        }).then(function (results){
                var promise = new Promise(function (resolve, reject) {
                baby.parse(results , {
                    dynamicTyping: true,
                    delimiter: "|",
                    complete: function (results, error) {
                        if(error)
                        {
                            console.log('Something went wrong');
                            reject(error);
                        }
                        else {
// define a local var here 
var transactionlist = [];

                                    for(i = 1; i < results.data.length - 1; i++)
                                {
                                    var transaction  = {
                                        column1 : results.data[i][14].substring(0, 6),
                                        column2: results.data[i][2].split(' ').join(''),
                                        column3: results.data[i][14].split(' ').join(''),
                                        column4: results.data[i][8],
                                        column5: results.data[i][9]
                                    }
                                transactionlist.push(transaction);

                                }//end for loop
// return transactionlist instead of updating global var
                                resolve([results, transactionlist]);
                                }
                        //console.log("Finished:", JSON.stringify(results.data));
                    }//end baby parse complete:function
                    });//end baby parse function
                }).then(function (results){
// load transactionlist again from passed values
var transactionlist = results[1];
results = results[0];
                    load.newload(transactionlist);
            });//end inner .then function
        });//end .then function
}//end incoming file function

I hope you can see the changes I made (they are not indented properly and commented). 希望您能看到我所做的更改(它们没有正确缩进和注释)。 Using this method, you'd never miss data while using callbacks / promises. 使用此方法,您将永远不会在使用回调/诺言时错过任何数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM