【问题标题】:Return value from nested callback instead of the parent function从嵌套回调而不是父函数返回值
【发布时间】:2013-08-13 04:42:09
【问题描述】:

我有一个父函数,它有多个回调,需要将最内层回调的结果传递给调用这个“父”函数的函数。由于 NodeJS 是异步的,我的父函数显然总是在回调执行之前返回。

如何让我的回调返回给调用者?

我现在正在使用的代码示例 -

var addNewUser = function(hash,name,number,time,syncTime){

// check here if the user exists or not by querying the phone number first
connection.query('SELECT user_id FROM users WHERE user_phone_number ="' +number+'"',function(err,rows,fields){

    if(rows[0]) return false;

    connection.query('INSERT INTO users (authorization_hash,user_name,user_phone_number,user_local_time,is_active,last_synced) VALUES ("'+hash+'","'+name+'","' + number+'","' +time+'","1","'+syncTime+'")',function(err,rows,fields){
    if(err) throw err;

    return true;    
        });

});
}

我希望能够将这个回调返回给调用者函数。

【问题讨论】:

  • 与实际问题无关,但示例代码存在问题,因为在INSERT 创建竞争条件之前通过SELECT 查询检查用户是否存在。查看INSERT INTO ... ON DUPLICATE KEY ... 或您的数据库的等效项。
  • 感谢您指出这一点! INSERT IGNORE 是否等效(我知道它会将所有错误都作为警告)。
  • 一个问题刚刚出现在我的脑海中,为什么我会遇到竞争条件,因为要插入的查询在回调中,并且总是会在选择查询完成后调用。如果我在这里缺少基本知识,请告诉我。
  • 用户 A SELECT ... 不返回任何行。用户 B SELECT ... 不返回任何行。用户 A INSERT ... 成功插入。用户 B INSERT ... 失败。在这种情况下,您可能可以检查从用户 B 的 INSERT 语句返回的错误,但最好使用原子 INSERT 语句为您进行检查。

标签: node.js asynchronous callback


【解决方案1】:

addNewUser 接受一个回调作为其最后一个参数,并让最里面的函数使用该值调用回调。

或者,您可以考虑让addNewUser 返回一个承诺。 RSVPQ 是 Promises/A 的实现:

function addNewUser(hash,name,number,time,syncTime) {
    var deferred = Q.defer();
    connection.query("SELECT ...", function(err, rows, fields) {
        if(err) { deferred.reject(err); }
        if(rows[0]) { deferred.reject("some reason"); }
        connection.query("INSERT INTO ...", function(err, rows, fields) {
            if(err) { deferred.reject(err); }
            deferred.resolve(rows[0]); // Whatever addNewUser would return normally
        });
    });

    return deferred.promise;
}

然后调用者会这样使用它:

addNewUser(...).then(function(newUserAdded) {
    // Do something with newUserAdded here
}, function(err) {
    // Do something with the error here
});

【讨论】:

  • 我最终将回调作为参数传递给函数,它完全按照我的意愿工作!我也意识到,基本上我不能从回调中返回一个值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
相关资源
最近更新 更多