在foreach声明中解决承诺

时间:2018-01-24 22:43:36

标签: node.js typescript firebase asynchronous google-cloud-functions

我试图解决多个承诺并在所有承诺解决时返回

我环顾四周但却无法找到解决方案,或者我只是不理解。

我的代码:

export const setLeagues = (res: any, leaguesArray: any) => {
leaguesArray.forEach((element: any) => {
    firebaseAdmin.firestore().collection('leagues').add(element)
        .catch((err: any) => { res.send(err) })
})

}

当forEach中的所有承诺都已解决时,我想要res.send('Successfully Added!)

2 个答案:

答案 0 :(得分:3)

您必须将所有承诺收集到数组中并使用Promise.all()生成新的承诺,只有在每个承诺得到解决后才能解决。一般形式是这样的:

const promises = []
things.forEach(thing => {
    promises.push(createPromiseForWork(thing))
})
const p = Promise.all(promises)
p.then(() => {
    // continue with your work
})

答案 1 :(得分:3)

如果您使用Promise.allmap

,这很简单
export const setLeagues = (res: any, leaguesArray: any) => {
    // Wrap in a Promise.all, and use .map instead of .forEach:
    Promise.all(leaguesArray.map((element: any) => {
        // Make sure to return promise here...
        return firebaseAdmin.firestore().collection('leagues').add(element)
            .catch((err: any) => { res.send(err) })
    })).then(() => {
        // Do things here that need to wait for all promises to resolve.
    })
}

我会注意到由于Promise.all的工作方式,您可能还想更改处理错误的方式。 Promise.all一旦被包装的承诺拒绝,就会拒绝,或者当所有包装的承诺解决时就会拒绝。因此,我建议您移动.catch链接Promise.all而不是内部承诺,以避免两次发送回复:

export const setLeagues = (res: any, leaguesArray: any) => {
    // Wrap in a Promise.all, and use .map instead of .forEach:
    Promise.all(leaguesArray.map((element: any) => {
        // Make sure to return promise here...
        return firebaseAdmin.firestore().collection('leagues').add(element)
    })).then(() => {
        // Do things here that need to wait for all promises to resolve.
        res.send('Successfully Added!')
    }).catch((err: any) => {
        // Consider moving error handler to here instead...
        res.send(err)
    })
}