Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何等待异步函数被执行?_Javascript_Node.js - Fatal编程技术网

Javascript 如何等待异步函数被执行?

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

我正在从不同的http请求获取板球比赛和分数。第一个获取匹配列表(具有唯一id),第二个获取分数使用唯一id。我需要完成第二个http请求(data.map函数),然后发送数据变量值(在res.json中,不使用超时)。我知道使用承诺/回调,但我对代码感到困惑。目前正在使用setTimeout等待,但我不想使用timeout。请帮忙

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更好的方法