Javascript Promises
Published: Wednesday, Feb 8, 2017 Last modified: Thursday, Nov 14, 2024
How do i implement a reject on a thrown error?
return Promise.resolve().then(() => {
if (!isGood) throw new Error('a wrench')
return doneStuff
})
Refactoring example
Bad:
function foo(data) {
return new Promise((resolve, reject) => {
console.log("debug data", data)
let video = {}
if (data.Item) {
video = data.Item
} else {
video = data
}
console.log("debug video", video)
resolve(video)
})
}
foo({ id: 12, title: "Back to the future"})
.then((output) => console.log(output))
Really bad (i.e. non-working) when using const
btw!
Good:
function foo (data) {
return Promise.resolve().then(() => {
console.log("debug data", data)
return data.Item || data
})
}
Or event just:
function foo (data) {
return Promise.resolve().then(() => data.Item || data)
}
prefer const
From Tim Oxley: seems a shame to lose benefits of const due to conditional initialisation. Instead of if/else + let I generally go for const + || in cases like the above, or a ternary :
// ternary
const thing = someCondition ? valueIfTrue : valueIfFalse
// multi-line conditional
const thing = (
multi &&
line &&
conditional
)
? valueIfTrue
: valueIfFalse
Single line arrows
for single line arrows, you don’t need the curlies or the return:
const a = () => { return get(uuidgen) }
// is equivalent to:
const b = () => get(uuidgen)
i.e. right hand side of the arrow can be a block or an expression
Promise refactoring
return Promise.resolve().then(() => { return })
is the same as:
return Promise.resolve()
Remember with promise you can resolve to either a promise or a value. if you resolve to a promise, the resolved value of the current promise will become the value resolved from the returned/resolved promise.
These are (mostly) equivalent, and will both resolve to 3
Promise.resolve().then(() => {
return 3
})
Promise.resolve().then(() => {
return Promise.resolve(3)
})
These are also (mostly) equivalent:
Promise.resolve()
Promise.resolve().then(() => {})
Promise.resolve().then(() => { return })
Promise.resolve().then(() => {
return Promise.resolve(undefined)
})
Two callbacks are bad!
function cb () {
console.log('called');
throw new Error('bad')
}
Promise.resolve()
.then(() => cb(null))
.catch(cb)
Correct is:
Promise.resolve()
.then(() => cb(null), cb)
Remember, then takes a second argument, e.g. p.then(onResolved, onRejected)
,
which fits perfectly with the errback signature callback(err)
!
More short hand action
foo.js
function foo (data) {
return new Promise((resolve, reject) => {
if (data.sdadas.dasdsada) { resolve(2) }
resolve(1)
})
}
module.exports = foo
main.js:
const foo = require('./foo.js')
foo()
//.then((data) => { console.log(data) })
.then(console.log)
// .catch((e) => { console.log("oh dear", e) } )
.catch(console.log)