Firebase云函数打字稿错误“并非所有代码路径都返回值" [英] Firebase cloud function typescript error "Not all code paths return a value"
问题描述
我正在使用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屋!