Disallow calling cb()
inside of a then()
(use util.callbackify instead) (promise/no-callback-in-promise
)
flat/recommended
, ✅
recommended
.
As a general rule, callbacks should never be directly invoked inside a Promise.prototype.then() or Promise.prototype.catch() method. That's because your callback may be unintentionally be invoked twice. It also can be confusing to mix paradigms.
Take the following example:
function callback(err, data) {
console.log('Callback got called with:', err, data)
throw new Error('My error')
}
// note: passing `err.message` for demo purposes, normally you would pass `err`
Promise.resolve()
.then(() => callback(null, 'data'))
.catch((err) => callback(err.message, null))
If you run this example, your output will look like the following:
Callback got called with: null data
Callback got called with: My error null
Boolean as to whether callbacks in timeout functions like setTimeout
will err.
Defaults to false
.
Ensure that your callback invocations are wrapped by a deferred execution function such as:
- setImmediate() or process.nextTick(): for Node.js.
- setTimeout(): for Browsers and Node.js.
// node.js
Promise.resolve()
.then(() => setImmediate(() => callback(null, 'data')))
.catch((err) => setImmediate(() => callback(err.message, null)))
// node.js and browsers
Promise.resolve()
.then(() => setTimeout(() => callback(null, 'data'), 0))
.catch((err) => setTimeout(() => callback(err.message, null), 0))
Your output will now look like the following:
Callback got called with: null data
Finally, if your callbacks have a Node.js signature (i.e.
callback(err, data)
), consider using util.promisify for promisifying your
callback code instead of combining the approaches.
String list of callback function names to exempt.