node.js - 使用请求承诺的 Node.js 嵌套回调不起作用
问题描述
我有一个非常简单的 nodejs/express API,它正在制作一个request.get()
inside request.post()
。我只是想 res.send 的响应正文request.get()
。
我尝试使用带有request
andrequest-promise... .then()
方法的简单回调函数无济于事。
const request = require('request')
const rp = require('request-promise')
app.get("/", (req, res) => {
var mapCenter
var address = "user query"
res.send(submitSearch());
function submitSearch() {
if (!mapCenter || !mapCenter.lat) {
googleMapsClient.geocode({
address: address,
}, function(err, res) {
if (!err) {
mapCenter = {lat:res.lat, lng:res.lng };
submitSearch();
}
});
} else {
var parameters = {
uri: domain,
form: {
latitude: mapCenter.lat,
longitude: mapCenter.
},
json: true
}
rp.post(parameters).then(function(res) {
return getResults(res.id)
})
}
}
function getResults(id) {
rp.get(domain+ id).then(function(res) {
return res.Results;
})
}
})
在app.get()
函数中,我希望我res.send(submitSearch())
能在我的调用中吐出我的return getResults(res.id)
声明,rp.post()
最终应该return res.Results
在我的getResults()
函数中给出。
最令人困惑的部分是我需要那个奇怪的 if 语句submitSearch()
来googleMapsClient
正确分配mapCenter
,然后submitSearch()
再次递归调用。我知道这是一个异步问题,我看过的无数线程和视频都没有涵盖这种特殊类型的案例。
解决方案
我建议使用promise API .geocode()
,然后你不要试图混合普通的回调和promise。这不仅会简化您的代码,而且还会使健壮的错误处理变得更加简单。到目前为止,我在这里看到的所有建议都缺少各种错误处理。我也看不出你需要在这里递归调用自己的任何理由。
const rp = require('request-promise');
app.get("/", (req, res) => {
let address = "user query";
// use promise interface for geocode
googleMapsClient.geocode({address}).asPromise().then(response => {
return {lat: response.lat, lng: response.lng };
}).then(mapCenter => {
const parameters = {
uri: domain,
form: {
latitude: mapCenter.lat,
longitude: mapCenter.lng
},
json: true
};
return rp.post(parameters);
}).then(id => {
return rp.get(domain+ id).then(res => res.Results);
}).then(results => {
res.send(results);
}).catch(err => {
// decide what to do here if there's an error
console.log(err);
res.sendStatus(500);
});
});
请注意,关于使用承诺的 Google 文档显示了这一点:
const googleMapsClient = require('@google/maps').createClient({
key: 'your API key here',
Promise: Promise
});
所以,当你初始化这样的东西以使用内置的 Promise 时,你可能需要告诉它使用哪个 Promise 实现。
推荐阅读
- java - 连接 AWS rds mysql 实例时获取 com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
- python - classinfo 类型列表
- amazon-web-services - 使用 AWS Cloudfront 和 S3 从 example.com 重定向到 www.example.com
- python - 从列表列表中复制浮点值
- perforce - 如何在 perforce 中列出当前用户和工作区?
- c++ - 为什么在模板函数中将两个 xtensor 表达式一起添加会错误广播?
- r - 如何在 r(ggmap,ggplot) 中修复地图上的名称和警告消息
- drupal - 尝试访问任何管理功能时出现 Drupal 8 错误
- arrays - 为什么我的数组的输出中有空格
- reactjs - React 功能组件,删除数据后如何重新渲染