How to pass extra data down a Parse Promise chain [duplicate]

喜你入骨 提交于 2019-12-02 17:41:55

You can make use of closures to do this, without the need for any extra objects or wrapping.

var promise = firstQuery.get(objectId).then(function(result1){
    return secondQuery.find()
    .then(function(result2) {
        return thirdQuery.find()
        .then(function(result3) {
            //can use result1, result2, result3 here
        });
    });
});

This "nested" syntax is identical in function to your "chaining" syntax.


EDIT based on comments

If your promise chain is long and complex enough that this nested syntax becomes ungainly, the logic is probably complex enough to merit abstraction into its own function.

function complexQuery(objectId) {
    var results = {};
    return firstQuery.get(objectId).then(function(result1) {
        results.result1 = result1;
        return secondQuery.find();
    })
    .then(function(result2) {
        results.result2 = result2;
        return thirdQuery.find();
    })
    .then(function(result3) {
        results.result3 = result3;
        return results;
    });
}

complexQuery(objectId)
.then(function (results) {
    //can use results.result1, results.result2, results.result3
});

Personally, I think that's easier to read and maintain than messing around with .bind.

You cannot use the parent scope trick

Well, since both the other answers do this, let me suggest a solution that doesn't. You can pass resolved promises along. This also has the added benefit of no nesting or closures.

This is based on the concept that promises are proxies for values already, so you don't actually have to create one long chain:

var firstObject = firstQuery.get(objectId);
var secondObject = firstObject.then(secondQuery.find.bind(secondQuery));
var thirdObject = secondObject.then(thirdQuery.find.bind(thirdQuery));
Promise.all(firstObject, secondObject, thirdObject).then(function(r1, r2, r3){
   // here you can use "r1", "r2" and "r3"
});

In standard promises, rather than parse code this would look similar:

Promise.all([firstObject, secondObject, thirdObject]).then(function(){
   var r1 = arguments[0], r2 = arguments[1], r3 = arguments[2]; 
   // here you can use "r1", "r2" and "r3"
});

With bluebird you can use .spread for a shortcut or .bind or actual context. If you absolutely must create one chain, you can pass context by returning multiple promises using Promise.all but I believe this approach is preferable.

If you want to keep your flat chaining syntax instead of nesting, you can use an object from the parent scope to share:

var shared = {};
var promise = firstQuery.get(objectId).then(function(result1){
    // save results to shared object
    shared.result1 = result1;
    return secondQuery.find();
}).then(function(result2){
    shared.result2 = result2;
    return thirdQuery.find();
}).then(function(result3) {
    // here I want to use "result1", "result2" and "result3"
    // just use shared.result1, shared.result2
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!