Javascript 如何等待异步函数被执行?
我正在从不同的http请求获取板球比赛和分数。第一个获取匹配列表(具有唯一id),第二个获取分数使用唯一id。我需要完成第二个http请求(data.map函数),然后发送数据变量值(在res.json中,不使用超时)。我知道使用承诺/回调,但我对代码感到困惑。目前正在使用setTimeout等待,但我不想使用timeout。请帮忙Javascript 如何等待异步函数被执行?,javascript,node.js,Javascript,Node.js,我正在从不同的http请求获取板球比赛和分数。第一个获取匹配列表(具有唯一id),第二个获取分数使用唯一id。我需要完成第二个http请求(data.map函数),然后发送数据变量值(在res.json中,不使用超时)。我知道使用承诺/回调,但我对代码感到困惑。目前正在使用setTimeout等待,但我不想使用timeout。请帮忙 app.get('/api/matches', (req, res) => { let url = `http://cricapi.com/api/m
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)
})
})
期望输出是板球比赛,但没有超时功能,当前输出是未定义的。将每个请求包装在一个
承诺中,并链接它们
Psuedo代码:
// 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)
将每个请求包装在一个承诺中
并链接它们
Psuedo代码:
// 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)
您应该使用async/await
来等待您的请求完成,因此您可以做的是,因此您需要使用支持承诺的request promise
包,这样您就可以使用async await,请参阅他们的
npm安装请求承诺
实现异步/等待,如下所示
const request=require('request-promise');
app.get('/api/matches',异步(req,res)=>{
让url=`http://cricapi.com/api/matches?apikey=${key}`
let{response,body}=等待请求({uri:url,方法:'GET'})
如果(response.statusCode!==200){
返回res.json({error:1,msg:err,})
}
让数据=body.matches.filter(匹配=>{
返回match.matchstart
})
等待Promise.all(data.map)(异步(元素,索引)=>{
let{response,body}=等待请求({uri:url,方法:'GET'})
element.score=body.score
数据推送(元素)
}))
返回res.json({error:0,matches:data})
}
您应该使用async/await
来等待您的请求完成,因此您可以做的是,因此您需要使用支持承诺的request promise
包,这样您就可以使用async await,请参见他们的
npm安装请求承诺
实现异步/等待,如下所示
const request=require('request-promise');
app.get('/api/matches',异步(req,res)=>{
让url=`http://cricapi.com/api/matches?apikey=${key}`
let{response,body}=等待请求({uri:url,方法:'GET'})
如果(response.statusCode!==200){
返回res.json({error:1,msg:err,})
}
让数据=body.matches.filter(匹配=>{
返回match.matchstart
})
等待Promise.all(data.map)(异步(元素,索引)=>{
let{response,body}=等待请求({uri:url,方法:'GET'})
element.score=body.score
数据推送(元素)
}))
返回res.json({error:0,matches:data})
}
尝试像这样在promise中包装映射
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
})
})
})
})
尝试像这样将地图包装在promise中
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
})
})
})
})
你在使用哪个请求库?你能在这里共享密钥吗?需要测试一种方法。你可以稍后重新生成它。Nodejs请求是我正在使用的;这一个:很抱歉,但我无法共享密钥。执行此代码时,网页中会显示分数,但使用超时函数等待数据更新。但是使用承诺,第二个http请求将被执行,数据将被更新。但在这里我不知道如何做。您使用的是哪个请求库?您可以在这里共享密钥吗?需要测试一种方法。您可以稍后重新生成它。Nodejs请求是我使用的;这一个:很抱歉,但我无法共享密钥。执行此代码时,请打分显示在网页中,但使用超时功能等待数据更新。但使用承诺,将执行第二个http请求并更新数据。但在这里,我不知道如何执行。虽然我理解,但我认为缺少requrl行。我将执行并告诉您输出。这不起作用,因为正在等待
不在async
函数中,因此是一个语法错误。请求。get
返回一个Promise
?如果不是,这也不会因为这个原因起作用。我更新了答案,将async添加到data.map回调函数中,然后它会work@lonesomeday是的,请求。获取退货承诺,见@onuriltan不,不会,这是完全相同的问题。我认为requrl行丢失了,尽管我理解它。我将执行并告诉您输出。这不会起作用,因为wait
不在async
函数中,因此是一个语法错误。请求.get
是否返回承诺?我更新了答案,在data.map回调函数中添加了async,然后它就可以了work@lonesomedayyes request.get返回承诺,见@onuriltan No,它不会,这是完全相同的问题。但在匹配列表http请求中,只有这样我才能获得唯一id,在相同的id中是score http请求,所以做出不同的承诺将处理它?承诺只不过是异步代码的包装器,可以附加回调。每当getMatch()返回时(作为参数传递给它的resolve函数),就会调用我的示例getScore()。当getScore()时complets结果被记录到控制台。将其他比特和片段放在适当的位置取决于您。请参阅:但在匹配列表http请求中,只有这样我才能获得唯一id,而在相同的id中是score http请求,因此做出不同的承诺将处理它?承诺只不过是异步代码w的包装器它可以附加回调。每当getMatch()返回时(作为参数传递给它的resolve函数),就会调用我的示例getScore()complets结果被记录到控制台。将其他位和块放在适当的位置取决于您。请参阅:非常感谢。它工作得非常好,正如我所预期的。我认为请求承诺和异步/等待是比ac更好的方法