I am pretty new in JavaScript technoogies and RxJS and I have the following doubt about how exactly works this code. It is taken from a project on which I am working and it works fine but I need to understand how exactly Promise.all() works and how it is used in this code.
So basically I have this method used to save multiple files on Firebase Store:
public async saveAsset(parameters: any, filesList: any[]) {
console.log("saveAsset() START, parameters: ", parameters);
if(filesList != null) {
//return await this.uploadFileIntoFirebaseStore(filesList);
let files: any[] = [];
if (filesList) { // If exist files that have to be updated
/**
* Retrieve files URLs list on Firebase Storage.
* uploadFileIntoFirebaseStore() receive the files list to be uploaded and return a Promise resolving
* an array of string representing the URLs where of the uploaded files.
*
*/
files = (await Promise.all(this.uploadFileIntoFirebaseStore(filesList)))
.map(url => {
console.log("UPLOADED URL: ", url);
return {
url
};
});
}
}
else {
//return await this.firestore.collection('assets').doc().set(parameters);
}
}
Basically my saveAsset() method receive the filesList parameter that is a list of files uploaded by the user that have to be saved on Firebase Storage. After that a file is saved I have to store the files URL.
In order to save these files it is used the uploadFileIntoFirebaseStore() method returning a Promise[]. So it is returning an array of n Promise objects.
So if I am well understanding the Promise concept (correct me if I am doing wrong assertion) it is my uploadFileIntoFirebaseStore() method is returning an object of type Promise that can basically do two different things:
- It can be resolved into an array of string (where each string represents the URL of an uploaded file on Firebase Storage).
- Be rejected in case an error occurs (I think that it could happens if a file upload fail).
So from what I have understand about the use of Promise.all() method is that it does something after that all the promises of my array are resolved. So in my code I have:
await Promise.all(this.uploadFileIntoFirebaseStore(filesList))
if I well understand the concept it means that my uploadFileIntoFirebaseStore perform the effective upload of my files in Firebase Storage and return an array of Promise where each promises can be resolve in the upload URL. This behavior is asyncronous because a file can be uploaded after or before other files. And here the first doubt: my array of Promise is immediatly returned and then the promises starts to be resolved in an asyncronous way or a Promise object is emitted when the upload of the related file start (something like an Observable). I think that the behavior is the first one but I am not sure.
The second doubt is related to the await keyword in front of the Promise.all() method. It means that this is an async method? From what I can understand the await keyword can be used only with async method.
The last doubt is: looking on various tutorial and documentation I found that often something like this:
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
Basically I have n Promise obbject that are passed as array to the Promise.all() method as array and then I have the then() method executing the arrow function when all the promises objects of the array are resolved (I can also have the catch() method to do something in case of rejection).
This is pretty different from my code where I have not the then() method that do something when all my promises are resolved. Instead my code use the RxJS map() operator on the list of the (resolved?) promises.
From what I can understand this map() operator iterates on the returned resolved promise containing the url of the related file in order to print it in the console and return it as Observable (it seems to me that map() always return an Observable, is it correct?)
How exactly works this syntax? Why is it not using the then()?