我正在从不同的HTTP请求中获取板球比赛和比分。第一个获取匹配列表(具有唯一ID),第二个获取得分使用唯一ID。我需要完成第二个http请求(data.map函数),然后发送数据变量值(在res.json中而不使用超时)。我知道使用Promises / Callbacks,但是我对代码感到困惑。当前正在使用setTimeout等待,但是我不想使用超时。请帮忙。
app.get('/api/matches', (req, res) => {
let url = `http://cricapi.com/api/matches?apikey=${key}`
request(url, { json: true }, (err, resp, body) => {
if (err) return res.json({
error: 1,
msg: err,
})
let data = body.matches.filter(match => {
return match.matchStarted
})
data.map((element, index) => {
let requrl = `http://cricapi.com/api/cricketScore?apikey=${key}&unique_id=${element.unique_id}`
request(requrl, { json: true }, (err, resp, body) => {
element.score = body.score
data.push(element)
})
})
setTimeout(()=>{
res.json({
error: 0,
matches: data
})
},2000)
})
})
期望板球的输出与其得分相匹配,但没有超时功能,当前输出不确定。
答案 0 :(得分:1)
您应该使用async/await
等待请求完成,所以您可以做的是,所以您需要使用支持Promise的request-promise
包,以便可以使用异步等待,请参阅documentation here
npm install request-promise
const request = require('request-promise');
app.get('/api/matches', async (req, res) => {
let url = `http://cricapi.com/api/matches?apikey=${key}`
let { response, body } = await request({ uri: url, method: 'GET' })
if (response.statusCode !== 200){
return res.json({ error: 1, msg: err,})
}
let data = body.matches.filter(match => {
return match.matchStarted
})
await Promise.all(data.map(async (element, index) => {
let { response, body } = await request({ uri: url, method: 'GET' })
element.score = body.score
data.push(element)
}))
return res.json({ error: 0, matches: data })
}
答案 1 :(得分:1)
尝试像这样在诺言中包装地图。
app.get('/api/matches', (req, res) => {
let url = `http://cricapi.com/api/matches?apikey=${key}`
request(url, { json: true }, (err, resp, body) => {
if (err) return res.json({
error: 1,
msg: err,
})
let data = body.matches.filter(match => {
return match.matchStarted
})
let newData = data.map((element, index) => {
return new Promise((resolve, reject) => {
let requrl = `http://cricapi.com/api/cricketScore?apikey=${key}&unique_id=${element.unique_id}`
request(requrl, { json: true }, (err, resp, body) => {
element.score = body.score
resolve(element);
})
});
})
Promise.all(newData).then(data => {
res.json({
error: 0,
matches: data
})
})
})
})
答案 2 :(得分:0)
将每个请求包装在Promise
中,并将它们链接起来。
伪代码:
// Promise for match
const getMatch = new Promise((resolve, reject) => {
// Do request, call resolve (or reject) when completed.
request(url, resolve);
});
// Promise for score
const getScore(id) = new Promise((resolve, reject) => {
// Do request, call resolve (or reject) when completed.
request(url, resolve);
});
// Chain promises
getMatch()
.then(match => getScore(match))
.then(profit => console.log(profit)
.catch(error => console.warn(error)