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.