函数仍然是异步调用的。我究竟做错了什么?

时间:2014-11-19 23:05:42

标签: javascript node.js promise

我的代码应该下载从我们学校的数据库导出的5个文件,然后根据第一个导出运行查询(将有其他四个文件的查询,并且有三个学校,所以我的功能需要可扩展)。

我有一个名为&#34的功能;下载"另一个叫做" updateSchedule的函数。"这两个功能都是分开工作的。



var download = function(file){
    var deferred = q.defer();
    var i = 1;
    var ftpGet = function(){
        var number = i++;
        toString(number);
        filename = file+number+'.csv';
        ftp.get(filename, filename, function(hadErr){
            if (hadErr){
                console.error('There was an error retrieving ' + filename);
            }else{
                console.log(filename + ' downloaded');
                if(i <= 5){
                    ftpGet();
                }else{
                    deferred.resolve();
                }
            }
        });
    }
    ftpGet();  
    return deferred.promise;
}

var updateSchedule = function(school, school_id){
    var deferred = q.defer();
    console.log('');
    connectionpool.getConnection(function(err, connection){
        if(err){
            console.error('CONNECTION error: ', err);
        }else{
            connection.query('DELETE FROM schedule WHERE school_id = "'+school_id+'"', function(err, rows){
                if (err) console.error(err);
                var path = './'+school+'_export1.csv';
                var reader = csv.createCsvFileReader(path, {'separator': ',','quote': '"','excape': '"','comment': ''});
                reader.addListener('data',function(data){
                    connection.query('INSERT INTO schedule SET section_id = "'+data[0]+'", student_id = "'+data[1]+'", course_number = "'+data[2]+'", period = "'+data[3]+'", teacher_id = "'+data[4]+'", school_id = "'+school_id+'"', function(err, rows){
                        if (err) console.error(err);
                        deferred.resolve();
                    }); 
                });
            });
            connection.release();
            console.log(school+' schedule updating...');
        }
    });
    return deferred.promise;
}
&#13;
&#13;
&#13;

但是,当我使用promises调用它们时,我收到错误消息,说它无法打开文件。我做错了什么?

&#13;
&#13;
download('lca_export').then(updateSchedule('lca', '517'));
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

改变这个:

download('lca_export').then(updateSchedule('lca', '517'));

到此:

download('lca_export').then(function() {
    updateSchedule('lca', '517');
});

您正在立即调用updateSchedule()并将结果传递给.then(),而不是将函数引用传递给稍后可以调用的.then()。因此,updateSchedule()download()完成其工作之前就已运行。这是一个非常常见的错误。请记住,如果函数名后面有parens,它将立即执行。如果它只是一个函数名或一个没有parens的匿名声明,那么你传递一个函数引用。


要清理的其他一些事情:

  1. var前面添加filename,使其成为局部变量而不是隐式全局变量。
  2. 删除toString(number)。充其量它根本不需要,因为你没有将结果分配给任何东西,所以没有做任何事情。最糟糕的是,它导致错误,因为没有函数toString()。仅供参考,数字会在添加到字符串时自动转换为字符串,因此您无需手动执行此操作。