I\'ve recently run into a certain situation a couple of times, which I didn\'t know how to solve properly. Assume the following code:
somethingAsync()
.the
Simply return a tuple:
async add(dto: TDto): Promise<TDto> {
console.log(`${this.storeName}.add(${dto})`);
return firebase.firestore().collection(this.dtoName)
.withConverter<TDto>(this.converter)
.add(dto)
.then(d => [d.update(this.id, d.id), d.id] as [any, string])
.then(x => this.get(x[1]));
}
You can't resolve a promise with multiple properties just like you can't return multiple values from a function. A promise conceptually represents a value over time so while you can represent composite values you can't put multiple values in a promise.
A promise inherently resolves with a single value - this is part of how Q works, how the Promises/A+ spec works and how the abstraction works.
The closest you can get is use Q.spread
and return arrays or use ES6 destructuring if it's supported or you're willing to use a transpilation tool like BabelJS.
As for passing context down a promise chain please refer to Bergi's excellent canonical on that.
You can check Observable represented by Rxjs, lets you return more than one value.
Simply make an object and extract arguments from that object.
let checkIfNumbersAddToTen = function (a, b) {
return new Promise(function (resolve, reject) {
let c = parseInt(a)+parseInt(b);
let promiseResolution = {
c:c,
d : c+c,
x : 'RandomString'
};
if(c===10){
resolve(promiseResolution);
}else {
reject('Not 10');
}
});
};
Pull arguments from promiseResolution.
checkIfNumbersAddToTen(5,5).then(function (arguments) {
console.log('c:'+arguments.c);
console.log('d:'+arguments.d);
console.log('x:'+arguments.x);
},function (failure) {
console.log(failure);
});
you can only pass one value, but it can be an array with multiples values within, as example:
function step1(){
let server = "myserver.com";
let data = "so much data, very impresive";
return Promise.resolve([server, data]);
}
on the other side, you can use the destructuring expression for ES2015 to get the individual values.
function step2([server, data]){
console.log(server); // print "myserver.com"
console.log(data); // print "so much data, very impresive"
return Promise.resolve("done");
}
to call both promise, chaining them:
step1()
.then(step2)
.then((msg)=>{
console.log(msg); // print "done"
})
You can return an object containing both values — there's nothing wrong with that.
Another strategy is to keep the value, via closures, instead of passing it through:
somethingAsync().then(afterSomething);
function afterSomething(amazingData) {
return processAsync(amazingData).then(function (processedData) {
// both amazingData and processedData are in scope here
});
}
Fully rather than partially inlined form (equivalent, arguably more consistent):
somethingAsync().then(function (amazingData) {
return processAsync(amazingData).then(function (processedData) {
// both amazingData and processedData are in scope here
});
}