【发布时间】:2021-04-11 02:31:31
【问题描述】:
我是 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 存储上的文件的列表。保存文件后,我必须存储文件 URL。
为了保存这些文件,它使用了返回 Promise[] 的 uploadFileIntoFirebaseStore() 方法。所以它返回一个由 n 个 Promise 对象组成的数组。
所以,如果我很好地理解了 Promise 概念(如果我做错了断言,请纠正我),我的 uploadFileIntoFirebaseStore() 方法正在返回一个 Promise 类型的对象,它基本上可以做两种不同的事情:
- 可以解析为字符串数组(其中每个字符串代表 Firebase 存储上上传文件的 URL)。
- 发生错误时被拒绝(我认为如果文件上传失败可能会发生这种情况)。
因此,根据我对 Promise.all() 方法的使用的理解,它会在我的数组的所有承诺都得到解决之后执行一些操作。所以在我的代码中我有:
await Promise.all(this.uploadFileIntoFirebaseStore(filesList))
如果我很好理解这个概念,这意味着我的 uploadFileIntoFirebaseStore 在 Firebase 存储中执行我的文件的有效上传并返回一个 Promise 数组,其中每个 Promise 都可以在上传 URL 中解析。这种行为是异步的,因为文件可以在其他文件之后或之前上传。这里是第一个疑问:我的 Promise 数组立即返回,然后 Promise 开始以异步方式解决,或者在相关文件开始上传时发出 Promise 对象(类似于 Observable)。我认为行为是第一个,但我不确定。
第二个疑问与Promise.all()方法前面的await关键字有关。这意味着这是一个 async 方法?据我了解,await 关键字只能用于异步方法。
最后一个疑问是:查看各种教程和文档,我发现经常是这样的:
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() 方法作为数组,然后我有 then() 方法执行箭头函数,当所有的 Promise 对象数组被解析(我也可以让 catch() 方法在被拒绝的情况下做一些事情)。
这与我的代码完全不同,在我的代码中我没有 then() 方法,当我的所有承诺都得到解决时,该方法会执行某些操作。相反,我的代码使用(已解决?)承诺列表中的 RxJS map() 运算符。
据我所知,此 map() 运算符迭代返回的已解决承诺,其中包含相关文件的 url,以便在控制台中打印它并将其作为 Observable 返回(在我看来 map() 总是返回一个 Observable,对吗?)
这种语法究竟是如何工作的?为什么不使用 then()?
【问题讨论】:
-
“这意味着这是一个异步方法?” - 是的,看第一行:
public async saveAsset。您可以改用.then,它们是可互操作的;async/await只是承诺的语法糖。(await Promise.all(arrayOfPromises))解析为数组;map不是 RxJS 函数,是数组方法。 -
我建议阅读例如如果您不清楚
async/await语法和承诺之间的交互,stackoverflow.com/q/34401389/3001761 以及与之相关的各种资源。 -
async&await只是promise&then的语法糖。他们真的是一回事。异步函数返回一个承诺,然后 await 将函数的其余部分放在事件循环中,并在完成后将检索到的值传递给它(.then(()=>{})的工作原理)。
标签: javascript typescript promise rxjs angular-promise