NodeJS Async / Await - создание файла конфигурации с вызовом API - PullRequest
3 голосов
/ 07 июня 2019

Я хотел бы иметь файл конфигурации с переменными, установленными с данными, которые я получаю из API.

Я думаю, что для этого нужно использовать функции async и await, иначе моя переменная останется неопределенной.

Но я не знаю, как интегрировать это и сохранить узел exports.myVariable = myData доступным в пределах async function?

Ниже приведен код, который я пытался написать для этого (все в одном файле):

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)
}

Вывод console.log(wallsData) показывает Promise { <pending> }, поэтому он не разрешен, и файл конфигурации продолжает выполняться без данных в wallData ...

Что мне не хватает?

Спасибо, Приветствия

Ответы [ 2 ]

3 голосов
/ 07 июня 2019

Обещание - это особый объект, который либо преуспевает с результатом, либо проваливается с отклонением.Синтаксис async-await является синтаксическим сахаром, помогающим справиться с обещаниями.

Если вы определите функцию как aync, она всегда вернет обещание.

Дажефункция, которая читается как

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

, возвращает обещание строки, а не только строки.И вам нужно подождать, пока он не будет решен или отклонен.

Это аналог:

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

или:

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

Ваш fetchWalls аналогично является обещаниемэто останется в ожидании какое-то время.Вы должны убедиться, что он либо будет успешным, либо неудачным, настроив обработчики then или catch во внешней области:

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

Внешняя область никогда не будет асинхронной, поэтому вы не можете использовать awaitтам.Вы можете использовать await только внутри других асинхронных функций.

Я бы также не использовал ваш try-catch для обработки обещаний внешней области.Я думаю, что вы путаете подход try-catch, который предназначен для использования в асинхронных функциях, так как там это помогает избежать вложения и читается как синхронный код:

Например, вы можете сделать внутриваше fetchWalls определение:

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.
    }

    ...
}
1 голос
/ 07 июня 2019

Можете ли вы изменить утверждения, как,

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)
}
...