NodeJS异步/等待+快递请求的递归

时间:2017-08-31 17:58:33

标签: javascript node.js express asynchronous recursion

我有一个名为GetAllData()的函数调用GetPurchaseData,它递归调用自身直到它加载所有数据。在

async function GetAllData(){
    console.log("starting loading purchase data");
        await GetPurchaseData();
        console.log("purchase data loaded")        
}

async function GetPurchaseData(){
         return new Promise(async function (resolve,reject){
            var Headers = {
                ....
            }
            await request({url: xxx, headers: Headers },async function(error, response, body) {
                    var tmp = JSON.parse(body)      
                    _.forEach(tmp.Purchases, p => purchaseData.push(p));                          

                    if (response.headers.pagination){
                        return await GetPurchasePaginatedData()
                    }
                    else{
                        console.log("done loading....")
                        return resolve("done")
                    }
            });
        })
}

Node JS打印以下输出:

starting loading purchase data 
done loading....

但它永远不会回到GetAllData打印

  

购买数据

它几乎看起来像是在功能上停滞不前,但我的意见是,某种程度上"返回解决方案("已完成")"没有回到初始调用,实际上将Promise标记为完成。

2 个答案:

答案 0 :(得分:1)

避免使用async/await Promise constructor antipattern(另请参阅here),并避免将async函数作为常规回调传递 - 您需要use the Promise constructor to promisify an existing callback API

async function GetPurchaseData() {
    var headers = {…};
    var promise = new Promise((resolve,reject) => { // not async!
        request({url: xxx, headers}, (error, response, body) => { // not async!
            if (error) reject(error);
            else resolve({response, body});
        });
    }); // that's it!

    var {response, body} = await promise;
    for (var p of JSON.parse(body).Purchases)
        purchaseData.push(p));                          

    if (response.headers.pagination) {
        return GetPurchasePaginatedData()
    } else {
        console.log("done loading....")
        return "done";
    }
}

答案 1 :(得分:0)

我对async / await没有太多经验,但从我读过的内容来看,代码看起来不应该是这样的。

async function GetAllData(){
    console.log("starting loading purchase data");
        await GetPurchaseData();
        console.log("purchase data loaded")        
}

async function GetPurchaseData(){
        let body = await request({url: xxx, headers: Headers })

        var tmp = JSON.parse(body)      
        _.forEach(tmp.Purchases, p => purchaseData.push(p));                          

        if (response.headers.pagination){
            return await GetPurchasePaginatedData()
        }
        else{
            console.log("done loading....")
            return "done"
        }
}