2016-06-29 5 views
1

Я написал один рекурсивный запрос для обновления данных на уровне базы данных мудрый или иерархический.Рекурсивный вызов в асинхронной функции в node.js

Я написал этот код:

let updateInvitationRewards = function(parent, level, callback) { 

    Service.customer.getOneCustomer({ 
    _id: parent 
    }, {}, {}, function(err, data) { 

    console.log(data.email); 
    level--; 
    if (data.parent) { 
     parent = data.parent.id; 
    } else if (level == 0 || data.parent == null) 
     callback("end"); 

    updateInvitationRewards(parent, level--, callback); 
    }); 

}; 

updateInvitationRewards(parent, level, function(string) { 
    console.log(string); 
    cb(); 
}); 

Этот запрос дает ошибку следующим образом:

Error: Callback was already called. 

Пожалуйста, помогите мне, я новичок в этих типов обратных вызовов.

+0

Возможно, вы попытаетесь вставить 'updateInvitationRewards (parent, level--, callback);' внутри условия 'if (data.parent)'? –

+0

Я не удалял код вставки из этой части кода для ясности данных ... но эта большая часть кода дает ошибку ... Обратный звонок уже был вызван .. Я не получаю его. –

+0

Ошибка возникает, когда вы вызываете обратный вызов функции более одного раза. В вашем коде, когда уровень становится равным 0 или когда родитель имеет значение null, вызывается обратный вызов. Но ваш код будет продолжать называть udpateInvitationRewards, даже если условие else if выполнено. Поэтому в следующий раз, когда родитель будет равен нулю, callback будет вызван во второй раз. Это может вызвать ошибку. –

ответ

2

Со всеми кронштейнами, мы имеем:

if (data.parent) { 
    parent = data.parent.id; 
} else if (level == 0 || data.parent == null) { 
    callback("end"); 
} 

updateInvitationRewards(parent, level--, callback); 

если level равен 0 или data.parent равно нулю, обратный вызов триггера, то updateInvitationRewards с той же функции обратного вызова.

Чтобы это исправить:

if (data.parent) { 
    parent = data.parent.id; 
} else if (level == 0 || data.parent == null) { 
    return callback("end"); // the execution stops here 
} 

updateInvitationRewards(parent, level--, callback); 
+0

Спасибо, очень :) –

1

На любой функции Обратный звонок должен быть вызван только один раз. Если обратный вызов вызывается более одного раза, наступает Error: Callback was already called..

Из примера кода видно, что функция будет рекурсивно вызываться. Таким образом, ошибка может появиться, когда уровень становится равным 0 или родительский элемент равен null.

Рассмотрите следующую ситуацию, когда уровень равен NULL или родительский null в первый раз, когда будет вызван обратный вызов. Но рекурсивный вызов будет продолжаться. Предположим, что при следующем выполнении, если родительский объект равен null, callback будет вызван во второй раз, и это вызовет ошибку.

Из кода я не мог видеть, что такое использование уровня, но я бы предложил следующий код для реализации, который гарантирует, что обратный вызов не будет вызван в следующий раз.

let updateInvitationRewards = function(parent, level, callback) { 

    Service.customer.getOneCustomer({ 
     _id: parent 
    }, {}, {}, function(err, data) { 
     console.log(data.email); 
     level--; 
     if (data.parent) { 
      parent = data.parent.id; 
      updateInvitationRewards(parent, level--, callback); 
     } else if (level == 0 || data.parent == null) 
      callback("end"); 
    }); 
}; 

updateInvitationRewards(parent, level, function(string) { 
    console.log(string); 
    cb(); 
}); 
Смежные вопросы