Итак, я вижу здесь несколько вопросов о том, как вы выполняете обещания. Легко ошибиться, если вы новичок в этом, так что не расстраивайтесь.
Итак, первая проблема - как вы звоните new Promise
. Этот конструктор принимает функцию с двумя параметрами: resolve
и reject
. Это функции, которые при вызове либо завершают, либо отклоняют обещание. Вы не делаете ни одного, поэтому первое обещание никогда не выполнится.
Вторая проблема, с которой вы столкнулись, заключается в том, что у вас есть вызовы по обещаниям внутри вызовов по обещаниям, но вы никогда не возвращаете обещания обратно в цепочку вызовов, поэтому вещи не объединяются должным образом.
В вашем случае, я не думаю, что new Promise()
это правильная конструкция в любом случае. Я думаю, вам нужно просто раздать обещание, которое завершается, когда все обещания, которые вы вызываете внутри цикла, завершаются. Поэтому вам нужно создать массив всех обещаний внутри цикла, а затем вызвать для них Promise.all
, чтобы получить новое обещание, которое завершается, когда все обещания в массиве выполнены.
Кроме того, весь этот процесс был бы намного проще, если бы вы просто везде использовали async / await вместо явного использования обещаний и вызовов then
. : -)
Я думаю, что то, что вы хотите сделать, выглядело бы примерно так, используя явные обещания:
// Don't need async if not awaiting
uploadPictures() {
// Build array of promises for each item in loop.
// Array.map is an easy way to do this.
let loop = this.files.map((file, index) => {
let path: string = `items/${Date.now()}_${this.files[index].name}`;
let ref = this.storage.ref(path);
// Inner promise - MUST RETURN THIS to chain properly
// Also, prefer flattened promise chains to nested one
return ref.put(file)
.then(snapshot => snapshot.ref.getDownloadURL())
.then(downloadLink => {
this.url.push(downloadLink);
console.log('Image is uploaded successfully and available at: ' + downloadLink);
});
});
return Promise.all(loop)
.then(() => {
console.log('hello from here!');
console.log(this.url);
return this.firestore.collection('items').doc(this.itemId).update({ pics: this.url });
});
}
При использовании async/await
это становится намного чище:
async uploadPictures() {
// Build array of promises for each item in loop.
// Array.map is an easy way to do this.
let loop = this.files.map(async (file, index) => {
let path: string = `items/${Date.now()}_${this.files[index].name}`;
let ref = this.storage.ref(path);
// await lets us avoid explicit returns or chaining
let snapshot = await ref.put(file);
let downloadUrl = await snapshot.ref.getDownloadURL();
this.url.push(downloadLink);
console.log('Image is uploaded successfully and available at: ' + downloadLink);
});
await Promise.all(loop);
console.log('hello from here!');
console.log(this.url);
await this.firestore.collection('items').doc(this.itemId).update({ pics: this.url });
}
Надеюсь, это поможет!