我怎样才能使链中的第二个块触发?
How can I make my second block in the chain trigger?
我有一些代码可以将一堆照片上传到服务器。
整个代码可以分为三部分:
从输入中捕获图片="files" 并将它们放入可验证的文件中,直到我调用方法 uploadPictures()。
然后我正在上传照片并将 url 推送到数组中以便我以后可以使用它们
最后,当上传结束时,我有 link 我想更新数据库 (Firestore) 中的某个文档
问题在于前两部分的代码运行良好。我可以让这条链既不使用 async/await 也不使用 Promises
async uploadPictures() {
let loop = new Promise( result => {
this.files.forEach((file, index) => {
let path: string = `items/${Date.now()}_${this.files[index].name}`;
let ref = this.storage.ref(path);
ref.put(file).then(snapshot => {
snapshot.ref.getDownloadURL().then(downloadLink => {
this.url.push(downloadLink);
console.log('Image is uploaded successfully and available at: ' + downloadLink);
})
});
});
}).then( () => {
console.log('hello from here!');
console.log(this.url);
this.firestore.collection('items').doc(this.itemId).update({ pics: this.url });
})
}
如有任何提示或建议,我将不胜感激!
所以我在这里看到了关于您如何履行承诺的多个问题。如果您是新手,很容易犯这些错误,所以不要为此感到难过。
所以第一个问题是您的呼叫方式 new Promise
。此构造函数采用具有两个参数的函数:resolve
和 reject
。这些函数在调用时会完成或拒绝承诺。你什么都不做,所以第一个承诺永远不会完成。
你遇到的第二个问题是你在 promise 调用中有 promise 调用,但你从来没有 return promise 备份调用链,所以事情没有正确地链接在一起。
就您而言,我认为 new Promise()
无论如何都不是正确的构造。我认为你需要简单地传递一个承诺,当你在循环中调用的所有承诺完成时完成。所以你需要做的是在循环中构造一个包含所有承诺的数组,然后对它们调用 Promise.all
以获得一个新的承诺,当数组中的所有承诺完成时完成。
此外,如果您只在所有地方使用 async/await 而不是显式使用 promises 和 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 });
}
希望对您有所帮助!
我有一些代码可以将一堆照片上传到服务器。
整个代码可以分为三部分:
从输入中捕获图片="files" 并将它们放入可验证的文件中,直到我调用方法 uploadPictures()。
然后我正在上传照片并将 url 推送到数组中以便我以后可以使用它们
最后,当上传结束时,我有 link 我想更新数据库 (Firestore) 中的某个文档
问题在于前两部分的代码运行良好。我可以让这条链既不使用 async/await 也不使用 Promises
async uploadPictures() {
let loop = new Promise( result => {
this.files.forEach((file, index) => {
let path: string = `items/${Date.now()}_${this.files[index].name}`;
let ref = this.storage.ref(path);
ref.put(file).then(snapshot => {
snapshot.ref.getDownloadURL().then(downloadLink => {
this.url.push(downloadLink);
console.log('Image is uploaded successfully and available at: ' + downloadLink);
})
});
});
}).then( () => {
console.log('hello from here!');
console.log(this.url);
this.firestore.collection('items').doc(this.itemId).update({ pics: this.url });
})
}
如有任何提示或建议,我将不胜感激!
所以我在这里看到了关于您如何履行承诺的多个问题。如果您是新手,很容易犯这些错误,所以不要为此感到难过。
所以第一个问题是您的呼叫方式 new Promise
。此构造函数采用具有两个参数的函数:resolve
和 reject
。这些函数在调用时会完成或拒绝承诺。你什么都不做,所以第一个承诺永远不会完成。
你遇到的第二个问题是你在 promise 调用中有 promise 调用,但你从来没有 return promise 备份调用链,所以事情没有正确地链接在一起。
就您而言,我认为 new Promise()
无论如何都不是正确的构造。我认为你需要简单地传递一个承诺,当你在循环中调用的所有承诺完成时完成。所以你需要做的是在循环中构造一个包含所有承诺的数组,然后对它们调用 Promise.all
以获得一个新的承诺,当数组中的所有承诺完成时完成。
此外,如果您只在所有地方使用 async/await 而不是显式使用 promises 和 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 });
}
希望对您有所帮助!