Nodejs中async和数据库问题

Nodejs中async和数据库问题

调用async的waterfall函数,为什么在数据库执行插入操作之后,再进行读操作,就不执行了呢,哪位高手解答一下? 代码如下: async.waterfall([ function(callback){db.GetData_All((‘where utag = 0 or utag = 1’),function(count){ console.log(count); callback(null,count); })}, function(count,callback){ if(count == 0){ lineReader.eachLine(‘url.txt’,function(line,last){ db.Insert(line,1); // console.log(line); }) } callback(null,count); }, function(count,callback){db.GetData((‘where utype = 1 and utag = 0’),function(line){ callback(null,line); }) } ],function(err,results){ console.log(results); callback(results);} )


2 回复

在Node.js中使用async库的waterfall函数时,可能会遇到一些异步操作导致的问题。你提到的情况是在执行数据库插入操作后,再进行读取操作时不执行。这通常是由于异步操作没有正确处理回调或错误导致的。

示例代码及解释

首先,我们需要确保每个异步操作都正确处理了回调。我们可以通过添加适当的日志来调试代码,并确保每个步骤都按预期执行。

const async = require('async');
const db = require('./db'); // 假设这是你的数据库模块
const fs = require('fs');
const readline = require('readline');

async.waterfall([
    function(callback) {
        db.GetData('where utag = 0 or utag = 1', function(count) {
            console.log(`获取到的数据数量: ${count}`);
            callback(null, count);
        });
    },
    function(count, callback) {
        if (count === 0) {
            const lineReader = readline.createInterface({
                input: fs.createReadStream('url.txt')
            });

            lineReader.on('line', function(line) {
                db.Insert(line, 1, function(err) {
                    if (err) return callback(err); // 如果插入失败,传递错误
                    console.log(`插入数据: ${line}`);
                });
            });

            lineReader.on('close', function() {
                callback(null, count);
            });
        } else {
            callback(null, count);
        }
    },
    function(count, callback) {
        db.GetData('where utype = 1 and utag = 0', function(lines) {
            console.log(`查询到的数据数量: ${lines.length}`);
            callback(null, lines);
        });
    }
], function(err, results) {
    if (err) {
        console.error(`发生错误: ${err.message}`);
        return;
    }

    console.log(`最终结果: ${results}`);
});

关键点解释

  1. 确保所有异步操作都处理了回调:在每个异步操作(如数据库插入和读取)完成后,确保调用了回调函数。
  2. 错误处理:在插入操作中,如果发生错误,则通过回调函数传递错误并停止后续操作。
  3. 读取文件的异步处理:使用readline模块来逐行读取文件,并在每行读取完毕后调用回调函数。
  4. 日志输出:添加日志输出以帮助调试,确保每个步骤都按预期执行。

通过这些调整,可以确保所有的异步操作都能正确执行,并且不会因为某些操作未完成而导致后续操作无法执行。


你的代码中存在一些逻辑和语法上的问题,导致异步操作可能没有按预期执行。特别是async.waterfall的回调处理以及数据库操作的顺序。以下是修改后的示例代码:

const async = require('async');
const fs = require('fs');
const readline = require('readline');

async.waterfall([
    function(callback) {
        db.GetData_All("where utag = 0 or utag = 1", function(count) {
            console.log(`Count: ${count}`);
            callback(null, count);
        });
    },
    function(count, callback) {
        if (count === 0) {
            const rl = readline.createInterface({
                input: fs.createReadStream('url.txt'),
                crlfDelay: Infinity
            });

            rl.on('line', (line) => {
                db.Insert(line, 1, () => {
                    // 插入操作完成后执行下一个任务
                    if (!rl.isEOF()) return;
                    callback(null, count);
                });
            });

            rl.on('close', () => {
                if (!rl.isEOF()) callback(new Error('File reading failed'));
            });
        } else {
            callback(null, count);
        }
    },
    function(count, callback) {
        db.GetData("where utype = 1 and utag = 0", function(lines) {
            console.log(`Lines: ${lines.length}`);
            callback(null, lines);
        });
    }
], function(err, results) {
    if (err) {
        console.error(`Error: ${err.message}`);
    } else {
        console.log(`Final Results: ${results}`);
    }
});

解释

  1. 第一个函数:从数据库获取所有符合条件的数据。
  2. 第二个函数:如果数据条目为零,则读取文件中的每一行并插入到数据库中。注意这里使用了readline模块来逐行读取文件,并确保在每行插入后继续执行。
  3. 第三个函数:再次从数据库获取符合条件的数据。

关键点

  • 确保每个异步操作完成后调用callback以传递控制权给下一个任务。
  • 使用readline模块来逐行读取文件,这样可以确保每个插入操作完成后才继续读取下一行。
  • async.waterfall的最终回调中检查是否有错误发生,并输出结果。

通过这种方式,你可以确保每个异步操作都能正确完成,并且不会遗漏任何步骤。

回到顶部