在我的代码中,这个Promise.all()语句究竟是如何工作的



我是JavaScript技术和RxJS的新手,我对这段代码的具体工作方式有以下疑问。它取自我正在工作的一个项目,它工作得很好,但我需要了解Promise.all((是如何工作的,以及它在这段代码中是如何使用的。

所以基本上我有这个方法来保存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);
}
}

基本上,我的saveAsset((方法接收filesList参数,该参数是用户上传的必须保存在Firebase Storage上的文件列表。在保存文件之后,我必须存储文件的URL。

为了保存这些文件,使用uploadFileIntoFirebaseStore((方法返回Promise〔〕。所以它返回一个由n个Promise对象组成的数组。

因此,如果我很好地理解Promise的概念(如果我做了错误的断言,请纠正我(,那就是我的uploadFileIntoFirebaseStore((方法正在返回一个Promise类型的对象,它基本上可以做两件不同的事情:

  1. 它可以解析为一个字符串数组(其中每个字符串表示Firebase Storage上上传文件的URL(
  2. 在出现错误的情况下被拒绝(我认为如果文件上传失败,可能会发生这种情况(

因此,根据我对Promise.all((方法的理解,方法在解析数组的所有Promise之后会执行一些操作。所以在我的代码中我有:

await Promise.all(this.uploadFileIntoFirebaseStore(filesList))

如果我很好地理解这个概念,这意味着我的uploadFileIntoFirebaseStore在Firebase Storage中有效地上传我的文件,并返回一个Promise数组,其中每个Promise都可以在上传URL中解析。这种行为是异步的,因为文件可以在其他文件之后或之前上载。这里有第一个疑问:我的Promise数组被立即返回,然后Promise开始以异步方式解析,或者在相关文件上传开始时发出Promise对象(类似于Observable(。我认为这种行为是第一种,但我不确定。

第二个疑问与Promise.all((方法前面的await关键字有关。这意味着这是一个异步方法?根据我的理解,await关键字只能与async方法一起使用。

最后一个疑问是:查看各种教程和文档,我发现通常是这样的:

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

基本上,我有n个Promise对象,它们作为数组传递给Promise.all((方法作为数组,然后当数组的所有Promise对象都被解析时,我有then((方法执行箭头函数(我也可以用catch((方法来做一些事情,以防被拒绝(。

这与我的代码非常不同,在我的代码中,我没有then((方法,当我的所有承诺都得到解决时,它会做一些事情。相反,我的代码在(resolved?(promise列表中使用RxJSmap((运算符。

据我所知,这个map((操作符迭代返回的包含相关文件url的解析promise,以便在控制台中打印它并将其返回为Observable(在我看来,map((总是返回Observable,这是正确的吗?(

这种语法究竟是如何工作的?为什么它不使用then((?

这是一个大问题,如果我没有回答所有方面,我很抱歉。仔细查看括号的数量:

files = (await Promise.all(this.uploadFileIntoFirebaseStore(filesList)))

这里,await的语法(请参见:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await)将等待传递给Promise.all的承诺

这意味着,上面的括号最终将求值为数组(而不是promise(。

对于字符串数组,可以调用map,因为它现在只是字符串数组。

如果你想使用then,你可以这样做:

Promise.all(...).then(urls => urls.map(...))

我希望这能回答你问题的基本方面。

Promise.all

它需要一系列承诺并并行执行。它遵循全部或无的机制

Promise.all([…](.then(console.log

还有一种方法Promise.allSettled即使其中一个承诺失败,也会认为成功。返回数据包含所有具有状态的结果

语法:-

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.all(promises)
.then((results) => results.forEach((result) => console.log(result)))
.catch(console.error);

最新更新