NodeJS Async / Await - Build configuration file with API call

夙愿已清 提交于 2019-12-23 20:09:21

问题


I would like to have a configuration file with variables set with data I fetch from an API.

I think I must use async and await features to do so, otherwise my variable would stay undefined.

But I don't know how to integrate this and keep the node exports.myVariable = myData available within an async function ?

Below is the code I tried to write to do so (all in the same file) :

const fetchAPI = function(jsonQuery) {
    return new Promise(function (resolve, reject) {
        var reqOptions = {
            headers: apiHeaders,
            json:jsonQuery,
        }

        request.post(apiURL, function (error, res, body) {
            if (!error && res.statusCode == 200) {
                resolve(body);
            } else {
                reject(error);
            }
        });
    });
}
var wallsData = {}
const fetchWalls = async function (){

    var jsonQuery = [{ "recordType": "page","query": "pageTemplate = 1011"}]

    let body = await utils.fetchAPI(jsonQuery)

    let pageList = await body[0].dataHashes
    for(i=0;i<pageList.length;i++){
        var page = pageList[i]
        wallsData[page.title.fr] = [page.difficultyList,page.wallType]
    }
    return wallsData
    throw new Error("WOOPS")
}

try{

    const wallsData = fetchWalls()
    console.log(wallsData)
    exports.wallsData = wallsData

}catch(err){
    console.log(err)
}

The output of console.log(wallsData) shows Promise { <pending> }, therefore it is not resolved and the configuration file keep being executed without the data in wallsData...

What do I miss ?

Thanks, Cheers


回答1:


A promise is a special object that either succeeds with a result or fails with a rejection. The async-await-syntax is syntactic sugar to help to deal with promises.

If you define a function as aync it always will return a promise.

Even a function like that reads like

const foo = async() => {
     return "hello";
}

returns a promise of a string, not only a string. And you need to wait until it's been resolved or rejected.

It's analogue to:

const foo = async() => {
     return Promise.resolve("Hello");
}

or:

const foo = async() => {
     return new Promise(resolve => resolve("Hello"));
}

Your fetchWalls similarly is a promise that will remain pending for a time. You'll have to make sure it either succeeds or fails by setting up the then or catch handlers in your outer scope:

fetchWalls()
    .then(console.log)
    .catch(console.error);

The outer scope is never async, so you cannot use await there. You can only use await inside other async functions.

I would also not use your try-catch for that outer scope promise handling. I think you are confusing the try-catch approach that is intended to be used within async functions, as there it helps to avoid nesting and reads like synchronous code:

E.g. you could do inside your fetchWalls defintion:

const fetchWalls = async function (){
    var jsonQuery = [{ "recordType": "page","query": "pageTemplate = 1011"}]

    try {
        let body = await utils.fetchAPI(jsonQuery)
    } catch(e) {
         // e is the reason of the promise rejection if you want to decide what to do based on it. If you would not catch it, the rejection would chain through to the first error handler.
    }

    ...
}



回答2:


Can you change the statements like,

try{

    const wallsData = fetchWalls();
    wallsData.then((result) => {
    console.log(result);
    });
    exports.wallsData = wallsData; // when importing in other file this returns as promise and we should use async/await to handle this.

}catch(err){


  console.log(err)
}


来源:https://stackoverflow.com/questions/56491580/nodejs-async-await-build-configuration-file-with-api-call

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!