node.js - Firebase 云函数:http 函数返回 null
问题描述
这是我想要做的。
- 我正在引入使用户能够搜索当地餐馆的功能。
- 我创建了一个 HTTP 云函数,当客户端下发关键字时,该函数会调用外部 API 来搜索关键字,获取响应并下发结果。
- 在执行 #2 时,我需要发出两个单独的 url 请求并合并结果。
当我检查时,该函数确实调用了 API,获取结果并将它们合并,没有任何问题。但是,由于某种原因,它只向客户端返回 null。
下面是代码:有人可以看看并告诉我我哪里出错了吗?
exports.restaurantSearch = functions.https.onCall((data,context)=>{
const request = data.request;
const k = encodeURIComponent(request);
const url1 = "an_url_to_call_the_external_API"+k;
const url2 = "another_url_to_call_the_external_API"+k;
const url_array = [ url1, url2 ];
const result_array = [];
const info_array = [];
url_array.forEach(url=>{
return fetch(url, {headers: {"Authorization": "API_KEY"}})
.then(response=>{
return response.json()
})
.then(res=>{
result_array.push(res.documents);
if (result_array.length===2) {
const new_result_array_2 = [...new Set((result_array))];
new_result_array_2.forEach(nra=>{
info_array.push([nra.place_name,nra.address_name])
})
//info_array is not null at this point, but the below code only return null when checked from the client
return info_array;
}
})
.catch(error=>{
console.log(error)
return 'error';
})
})
});
提前非常感谢!
解决方案
您应该使用而不是在循环中Promise.all()
单独运行每个承诺(获取请求) 。如果is not forEach
,我也看不到函数返回任何内容。我可以看到您只发出 2 个请求,但最好处理所有可能的情况,因此如果条件不满足,请尝试添加 return 语句。尝试将您的代码重构为此(我使用了异步函数):result_array.length
2
exports.restaurantSearch = functions.https.onCall(async (data, context) => {
// Do note the async ^^^^^
const request = data.request;
const k = encodeURIComponent(request);
const url1 = "an_url_to_call_the_external_API" + k;
const url2 = "another_url_to_call_the_external_API" + k;
const url_array = [url1, url2];
const responses = await Promise.all(url_array.map((url) => fetch(url, { headers: { "Authorization": "API_KEY" } })))
const responses_array = await Promise.all(responses.map((response) => response.json()))
console.log(responses_array)
const result_array: any[] = responses_array.map((res) => res.documents)
// Although this if statement is redundant if you will be running exactly 2 promises
if (result_array.length === 2) {
const new_result_array_2 = [...new Set((result_array))];
const info_array = new_result_array_2.map(({place_name, address_name}) => ({place_name, address_name}))
return {data: info_array}
}
return {error: "Array length incorrect"}
});
如果您只运行 2 个 Promise,则其他选项是:
// Directly adding promises in Promise.all() instead of using map
const [res1, res2] = await Promise.all([fetch("url1"), fetch("url2")])
const [data1, data2] = await Promise.all([res1.json(), res2.json()])
推荐阅读
- python - 更新 DynamoDB 表然后获取新值
- xml - 从不在同一行的xml标签中提取数据
- php - 使用PHP:从给定点查找多边形中最近的点
- matlab - 在轮廓图上覆盖等值线
- r - 将数据帧从宽格式转换为长格式,密钥存储在 R 行中
- spring-integration - 发布订阅流后从入站适配器移动文件
- node.js - 捕获错误 401 adonis.js 错误 E_INVALID_SESSION: Invalid session
- angular - 使用 Ahead-of-Time 编译时如何更改 Angular 的插值字符?
- machine-learning - PyTorch 中的 torch.optim.SGD 结果为 NaN
- google-kubernetes-engine - 每个客户是否应该拥有自己的 Kubernetes 集群