簡體   English   中英

遍歷包含 promise 的數組並等待完成

[英]Iterate over array with promise inside and wait to finish

我正在嘗試使用 Firestore 快照填充響應數組,並在每個快照中創建存儲文件的下載鏈接。 我嘗試使用 Promises 解決方案,但響應數組始終為 null。

docRef.get().then(async (snapshot: any) => {
                await snapshot.docs.forEach(async (attachment: any) => {                    
                    await downloadFile(attachment.data()["paths"]).then((urls: any) => {
                        attachmentList.push({
                            "id": attachment.id,
                            "created_at": attachment.data()["created_at"],
                            "paths": urls,
                            "content_types": attachment.data()["content_types"]
                        })
                    }).catch(error => {
                        res.status(400).send({
                            "code": "ERROR",
                            "message": error
                        });
                    })  
                })
            })
            res.send({
                "code": "ok",
                "message": attachmentList
            });

這是Promise.all的經典案例。 試試這個

const snapshot = await docRef.get();
const results = await Promise.all(
  snapshot.docs.map(
    attachment => downloadFile(attachment.data()["paths"])
  )
);
console.log(results);

如果我們清理你的縮進,你可以很快明白為什么你沒有為“消息”返回任何東西,不管你在那里嘗試什么 - 它在任何異步內容甚至執行之前返回響應:

docRef.get()
    .then(async (snapshot: any) => {
        // <-- this line won't run
        /* ... removed for conciseness */
    });

res.send({
    "code": "ok",
    "message": attachmentList
});
// <-- before this line (and the response is sent already!)

你要做的是組裝你的附件數組,然后返回它們:

docRef.get()
    .then((snapshot) => {
        return Promise.all(
            snapshot.docs.map(async (attachmentDocSnapshot) => {
                const { paths, created_at, content_types } = attachmentDocSnapshot.data();
                const urls = await downloadFile(paths);
                return {
                    content_types,
                    created_at,
                    id: attachmentDocSnapshot.id,
                    paths: urls
                };
            })
        );
    })
    .then((attachmentInfoList) => {
        res.json({                                  // .json() is more semantic
            "code": "OK",                           // for consistency, capitalized
            "message": attachmentInfoList
        });
    })
    .catch((err) => {
        console.error(`Failed to collect information about the attachments for Doc #${docRef.id}: `, error);
        res.status(500).json({                      // 500 Internal Server Error
            "code": "ERROR",
            "message": error.code || error.message  // Send back as little information about the error as possible
        });
    });

雖然上面的代碼有效,但它並不漂亮。 所以讓我們把它改造成一個孩子 function:

async function getAttachmentInfoFromSnapshot(attachmentDocSnapshot) {
    const { paths, created_at, content_types } = attachmentDocSnapshot.data();
    const urls = await downloadFile(paths);
    return {
        content_types,
        created_at,
        id: attachmentDocSnapshot.id,
        paths: urls
    };
}

docRef.get()
    .then((snapshot) => Promise.all(
        snapshot.docs.map(getAttachmentInfoFromSnapshot)
    ))
    .then((attachmentInfoList) => {
        res.json({                                  // .json() is more semantic
            "code": "OK",                           // for consistency, capitalized
            "message": attachmentInfoList
        });
    })
    .catch((err) => {
        console.error(`Failed to collect information about the attachments for Doc #${docRef.id}: `, error);
        res.status(500).json({                      // 500 Internal Server Error
            "code": "ERROR",
            "message": error.code || error.message  // Send back as little information about the error as possible
        });
    });

注意:您可以重寫上面的內容以在下一層使用async / await語法,但如果這樣做,請確保將其全部包裝在try / catch塊中以處理沿途的任何錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM