我可以在 .then 参数中使用承诺吗?

Can I use a promise in .then arguments?

我有两个功能:

第一个做一个 http post 得到一个 xml 字符串

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)
        })
    })
}

xml 到对象的第二次转换

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)
        })
    })
}

现在我想调用post请求,得到一个xml字符串,然后将其转化为一个对象,请问哪个是正确的,为什么:

post(url, formData).then( function (xml) {

    xmlToObject(xml).then( function (obj) {
        // do some work
    })

})

post(url, formData).then( function (xml) {

    xmlToObject(xml).then( function (obj) {
        return obj
    })

}).then( function (obj) {
    // do some work
})

post(url, formData).then( function (xml) {

    return xmlToObject(xml)

}).then( function (obj) {
    // do some work
})

post(url, formData).then( xmlToObject )
.then( function (obj) {
    // do some work
})

您可以通过以下方式使用上述函数构建您的承诺链:

post(url, formData)
  .then(xmlToObject)
  .then(doSomeWork);

function doSomeWork(obj) {
  //do some work
}

这个是正确的

post(url, formData).then( function (xml) {
    return xmlToObject(xml)
}).then( function (obj) {
    // do some work
});

原因:

当 return 承诺解析器中的承诺时,您可以继续添加。然后 handler.Maybe 承诺旨在使用此功能来避免回调地狱

promise.then(function(obj) {
    return obj
})

没有意义,应该只用 promise 代替(省略 then 调用)。

….then(function(xml) {    
    xmlToObject(xml)
// ^ note the missing `return`
}).then(function(obj) {
    …
});

是您 collection 中唯一一个 不起作用的。如果您不 return 任何东西,则不会等待任何东西(并且不会获得任何结果),链中的下一个回调将立即调用 undefined.

post(url, formData).then(function(xml) {
    xmlToObject(xml).then(function(obj) {
        // do some work
    })
})

这确实有效,但很麻烦。您将得到厄运的缩进金字塔,并且通过忽略 return 来自 then 回调的任何内容,您将无法将任何内容链接到外部承诺。这对于处理链末端的错误尤为重要。

因此,链接 promise 的正确方法是

post(url, formData).then(function(xml) {
    return xmlToObject(xml);
}).then(function (obj) {
    // do some work
})

完全等同于较短的

post(url, formData).then(xmlToObject).then(function(obj) {
    // do some work
});

如果您想同时使用 xmlobjnesting (with return!) is an option out of many

我更喜欢清晰链接这个变体:

return Promise.resolve()
    .then(function () {
        return post(url, formData);
    })
    .then(function (xml) {
        return xmlToObject(xml);
    })
    .then(function (object) {
        return something;
    });