I have 2 functions:
the first one make an http post to get an xml string
function post(url, formData) {
return new Promise(function (resolve, reject) {
// make an http post and get results (xml string)
request(url, formData, function(error, xml) {
if (error) reject(error)
resolve(xml)
})
})
}
the second transform that xml to an object
function xmlToObject(xml) {
return new Promise( function (resolve, reject) {
// transform xml string to an object using xml2js for example
xml2js(xml, function(error, obj) {
if (error) reject(error)
resolve(obj)
})
})
}
Now I want to call post request and get an xml string and then transform it to an object, so which one is correct and why:
post(url, formData).then( function (xml) {
xmlToObject(xml).then( function (obj) {
// do some work
})
})
Or
post(url, formData).then( function (xml) {
xmlToObject(xml).then( function (obj) {
return obj
})
}).then( function (obj) {
// do some work
})
Or
post(url, formData).then( function (xml) {
return xmlToObject(xml)
}).then( function (obj) {
// do some work
})
Or
post(url, formData).then( xmlToObject )
.then( function (obj) {
// do some work
})
promise.then(function(obj) { return obj })
is pointless and should be replaced by just promise
(omitting the then
call).
….then(function(xml) { xmlToObject(xml) // ^ note the missing `return` }).then(function(obj) { … });
is the only one in your collection that does not work. If you don't return
anything, nothing can be awaited (and no result be obtained), and the next callback in the chain will be invoked immediately with undefined
.
post(url, formData).then(function(xml) { xmlToObject(xml).then(function(obj) { // do some work }) })
That does work but is cumbersome. You'll get the indentation pyramid of doom, and by neglecting to return
anything from the then
callbacks you make it impossible to chain anything to the outer promise. This is especially important for handling errors at the end of the chain.
The correct way of chaining promises is therefore
post(url, formData).then(function(xml) { return xmlToObject(xml); }).then(function (obj) { // do some work })
which is exactly equivalent to the shorter
post(url, formData).then(xmlToObject).then(function(obj) { // do some work });
If you want to do some work using both xml
and obj
, nesting (with return
!) is an option out of many.