Firebase云函数打字稿错误“并非所有代码路径都返回值" [英] Firebase cloud function typescript error "Not all code paths return a value"

查看:119
本文介绍了Firebase云函数打字稿错误“并非所有代码路径都返回值"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firebase云功能和Firestore交易来减少基于购买的可用产品数量.在部署时,它返回错误错误TS7030:并非所有代码路径都返回一个值"

I am using firebase cloud function and firestore transaction to decrease the available quantity of product based on purchases. At the time of deploy it returns the error "error TS7030: Not all code paths return a value"

这是代码

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';


admin.initializeApp();
const db = admin.firestore()

exports.newOrder = functions.firestore
.document('orders/{orderId}')
.onCreate(async (snap, context) => {

    try {
        const data = snap.data();
        if (data === undefined) return null

        const itemList = data.list as Array<any>
        const productId: Set<string> = new Set<string>();

        itemList.forEach((item) => {
            productId.add(item.id)
        })
        return db.runTransaction(async t => {

            const promises: Promise<admin.firestore.DocumentSnapshot>[] = []
            productId.forEach(i => {
                const p = admin.firestore().doc('Products/' + i).get()
                promises.push(p)
            })
            const docs=await Promise.all(promises)
            docs.forEach(doc => {
                if (!doc.exists) {
                    return Promise.reject("Product deleted")
                }
            })
            itemList.forEach(j => {
                if (j.variation === '-') {
                    const available = docs[j.id].get('available')
                    const needed = j.quantity
                    if (available < needed) {
                        return Promise.reject("Product out of stock")
                    }
                }
                else {
                    const variations = docs[j.id].get('variation') as Map<string, any>
                    for (const i in variations.keys) {
                        if (i === j.variation) {
                            const needed = j.quantity
                            const available = docs[j.id].get('variation').get(i).get('quantity')
                            if (available < needed) {
                                return Promise.reject("Product out of stock")
                            }
                        }
                    }
                }
            })
            itemList.forEach(j => {
                if (j.variation === '-') {
                    const available = docs[j.id].get('available')
                    const needed = j.quantity
                    t.update(db.doc('Products/' + j.id), { 'available': available - needed })
                }
                else {
                    const variations = docs[j.id].get('variation') as Map<string, any>
                    for (const i in variations.keys) {
                        if (i === j.variation) {
                            const needed = j.quantity
                            const available = docs[j.id].get('variation').get(i).get('quantity')
                            t.update(db.doc('Products/' + j.id), { [`variation.${i}.quantity`]: available - needed })
                        }
                    }
                }
            })
            return Promise.resolve("Product quantity updated")
        })
    }
    catch (error) {
        console.log(`error ${error}`)
        return null
    }
});

这是部署中显示的错误

 src/index.ts:30:30 - error TS7030: Not all code paths return a value.

 30                 docs.forEach(doc => {
                            ~~~~~~~~

 src/index.ts:35:34 - error TS7030: Not all code paths return a value.

 35                 itemList.forEach(j => {
                                ~~~~~~


 Found 2 error 

如何解决该错误.

2个循环检查产品是否被删除以及产品是否缺货.如果满足条件,我想退出该功能.请帮助我.

2 loops mentioned in the error checks whether the products is deleted or not and product is out of stock or not. If it satisfies the condition i want to exit from the function. Please help me.

推荐答案

问题比看起来更深.您可能会误解 return 语句在 forEach 中执行的操作.该代码的结构就像假定要检查是否 doc.exists 中的任何一个为false,如果为false,则尽早返回,但是按这样编写,它将从迭代回调中返回.code> forEach 不使用回调返回值,承诺拒绝仍未得到处理.

The probles is deeper than it may seem to be. You're possibly misunderstanding what does return statement do inside the forEach. The code is structured as if it was assumed to check if any of the doc.exists is false and return early if so, but written as this, it will return from the iteration callback.. and since forEach doesn't use the callback return value, the promise rejection remains unhandled.

实现此结果的正确方法如下:

The proper ways of achieving this result would be the following:

1)只需直接检查您需要检查的内容:

1) Just check directly what you need to check:

if (docs.findIndex(doc => !doc.exists) !== -1) {
    return Promise.reject("Product deleted");
}

2)使用 for..in for..of 循环,而不是 forEach :

2) Use the for..in or for..of loop instead of forEach:

for (doc of docs) {
    if (!doc.exists) {
        return Promise.reject("Product deleted")
    }
}

3)使用 map await 结果(不建议使用,因为您实际上不需要映射):

3) Use the map and await the result (not recommended, since you don't really need mapping):

await Promise.all(docs.map(doc => {
    if (!doc.exists) {
        return Promise.reject("Product deleted")
    }
    return null
})

请注意,在这种情况下,结果数组中任何被拒绝的承诺都应触发对外部承诺的拒绝.

Note that in this case any rejected promise inside the resulting array should trigger the rejection of the outer promise.

旁注:您永远不需要显式的 Promise.reject()调用.由于您的函数是异步的,因此您可以简单地 throw 用作错误的东西-无论如何,这都会转化为promise拒绝.

Side note: you don't ever need the explicit Promise.reject() call. As your function is async, you can simply throw something you'll use as an error - this will be transformed into promise rejection anyway.

这篇关于Firebase云函数打字稿错误“并非所有代码路径都返回值"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆