Ответ 1
Не совсем понятно, о чем спрашивают, и вы не включаете свою функцию solve()
, которая может быть здесь важна, поэтому я могу дать вам несколько общих советов.
У вас есть что-то вроде этого:
}).then(function(end) {
cb(null, end);
}).catch(function(err) {
if (err) console.log(err);
});
Первая часть (then
) предполагает, что обратный вызов cb()
принимает ошибку как первый аргумент и значение как второй аргумент, следуя обычному соглашению Node обратных вызовов.
Но тогда во второй части (catch
) вы не вызываете обратный вызов с ошибкой. Кроме того, if (err)
является избыточным, поскольку в обработчике catch
всегда будет ошибка, если только функция solve()
не возвращает отклоненное обещание с false
или null
, указанное в качестве причины отклонения, - и даже тогда, независимо от причины отклонения, обратный вызов всегда должен вызываться в случае ошибки:
}).then(function(end) {
cb(null, end);
}).catch(function(err) {
console.log(err);
cb(err);
});
Таким образом, вы не получите ситуации, когда callback никогда не вызывается и ждет навсегда. Когда вы смешиваете promises с традиционными обратными вызовами, вам нужно помнить несколько вещей:
Любая функция, которая получает обратный вызов в качестве аргумента, должна удостовериться, что этот обратный вызов вызван и что он вызывается ровно один раз. Это ваша ответственность как автор функции для обеспечения этого. В случае ошибки вы должны запустить:
callback(error);
и в случае успеха вы должны позвонить:
callback(null, data);
Таким образом, callback
может знать, когда операция завершена и завершилась ли она с успехом или неудачей, проверив свой первый аргумент:
function (err, data) {
if (err) {
console.log('Error:', err);
} else {
console.log('Success:', data);
}
}
Весь вызов функции, выполняющей обратный вызов, обычно:
functionTakingCallback('some', 'arguments', function (err, data) {
if (err) {
console.log('Error:', err);
} else {
console.log('Success:', data);
}
});
С другой стороны, если функция возвращает обещание, вы используете ее следующим образом:
functionReturningPromise('some', 'arguments')
.then(function (data) {
console.log('Success:', data);
})
.catch(function (err) {
console.log('Error:', err);
});
Нет необходимости тестировать err
в этом случае.
Обратные вызовы всегда следует вызывать ровно один раз. promises всегда должен быть либо разрешен, либо отклонен в конце концов. Использование различно, и ответственность как вызывающего, так и вызываемого абонента различна. Когда вы смешиваете эти два стиля - функции, которые используют традиционные Node -образные обратные вызовы и функции, которые возвращают promises - тогда вы должны быть осторожны с этими различиями.
Иногда вы можете преобразовывать функции, возвращающие обратные вызовы, в функции, возвращающие promises, используя библиотеки, такие как Bluebird и promisify()
и promisifyAll()
, чтобы иметь согласованный API для всех ваших асинхронных функций во всей кодовой базе. См:
- http://bluebirdjs.com/docs/api/promise.promisify.html
- http://bluebirdjs.com/docs/api/promise.promisifyall.html
Вы можете увидеть некоторые другие ответы, где я объясню разницу между обратными вызовами и promises и как их использовать вместе более подробно, что может быть полезно для вас в этом случае: