JavaScript: преобразование RSS в JSON в приложении AWS Lambda Node - PullRequest
0 голосов
/ 25 февраля 2019

В настоящее время я работаю над написанием функции в AWS Lambda.Я хочу преобразовать RSS-канал в JSON и передать его в виде ответа в теле при создании конечной точки Lambda.

Я использую пакет npm для преобразования RSS в JSON.Тем не менее, когда я запускаю код.Я вижу, что я не определен при преобразовании URL-адреса RSS.Вот следующий код:

const feed = require('rss-to-json');

exports.handler = async (event) => {
  let rssFeed = event.queryStringParameters.rssFeed;
  let rssAsJsonData = convertRssIntoJson(rssFeed);

  return sendRes(200, rssAsJsonData);
};

const sendRes = (status, body) => {
  var response = {
    isBase64Encoded: true|false,
    statusCode: status,
    headers: {
      "Content-Type": "application/json"
    },
    body: body,
  };
  return response;
};

function convertRssIntoJson (rssFeed) {
  console.log(rssFeed);
  return feed.load(rssFeed, function(err, rss){
    if(err) {
      console.log("Error: ${err}");
      return;
    }
    console.log(rss)
    return rss;
  });
};

Однако в логах я получаю undefined при console.log(rssAsJsonData).enter image description here

Однако при отладке я смог увидеть console.log(rss), работающий при изменении тела на body: json.stringify("TESTING") enter image description here

Однако, это работало только при входе в консоль, а не когда я пытался передать его в тело body: body, Не могу найти ошибку.Я перехожу из Ruby в JavaScript для этого проекта, может быть, я что-то упустил.

Я использую Почтальон для звонков: enter image description here

1 Ответ

0 голосов
/ 26 февраля 2019
function convertRssIntoJson (rssFeed) {
  console.log(rssFeed);
  return feed.load(rssFeed, function(err, rss){
    if(err) {
      console.log("Error: ${err}");
      return;
    }
    console.log(rss)
    return rss;
  });
};

Часть кода выше является обратным вызовом.Под капотом feed.load является асинхронным, что делает ваш обратный вызов выполненным асинхронно.

Теперь, когда вы вызываете свою функцию следующим образом:

let rssAsJsonData = convertRssIntoJson(rssFeed);

ваш rss объект внутри convertRssIntoJson пока не имеет значения, поскольку обратный вызов до сих пор не заполнен.Вот откуда взялись ваши undefined.

Сами обратные вызовы не делают код асинхронным по умолчанию, но NodeJS работает с неблокирующей моделью ввода-вывода и, поскольку feed.load является вызовом ввода-вывода, он будетвыполняется асинхронно.

У вас есть несколько вариантов, но я перечислю только два.Не очень хорошее и приятное решение:

1) Не очень хороший способ исправить это - добавить обратный вызов в качестве аргумента к вашей функции convertRssIntoJson и передать значение этого * 1017.* объект вверх по течению.Не очень хороший полный код можно найти ниже:

const feed = require('rss-to-json');

exports.handler = async (event) => {
    let rssFeed = event.queryStringParameters.rssFeed;

    convertRssIntoJson(rssFeed, (err, data) => {
        if (err) {
            return sendRes(500, { message: 'There was an err: ' + err.message })
        }
        return sendRes(200, data)
    })
};

const sendRes = (status, body) => {
    var response = {
        isBase64Encoded: true | false,
        statusCode: status,
        headers: {
            "Content-Type": "application/json"
        },
        body: body,
    };
    return response;
};

const convertRssIntoJson = (rssFeed, callback) => {
    console.log(rssFeed);
    feed.load(rssFeed, function (err, rss) {
        if (err) {
            console.log("Error: ${err}");
            callback(err, undefined)
        }
        console.log(rss)
        callback(undefined, rss)
    });
};

2) Это хорошее, чистое, элегантное и рекомендуемое решение.Оберните ваш обратный вызов в Promise, как это

function convertRssIntoJson(rssFeed) {
    console.log(rssFeed);
    return new Promise((res, rej) => {
       feed.load(rssFeed, function (err, rss) {
            if (err) {
                console.log("Error: ${err}");
                return rej(err)
            }
            console.log(rss)
            return res(rss)
        });
    })
};

Поскольку ваш обработчик async, это означает, что он может просто await на Promises.

Таким образом, ваш код клиента теперьпросто как:

return sendRes(200, await convertRssIntoJson(rssFeed));

Ваш окончательный код будет выглядеть так (я немного изменил рефакторинг для использования функций стрелок):

const feed = require('rss-to-json');

exports.handler = async (event) => {
    let rssFeed = event.queryStringParameters.rssFeed;

    return sendRes(200, await convertRssIntoJson(rssFeed));
};

const sendRes = (status, body) => {
    var response = {
        isBase64Encoded: true | false,
        statusCode: status,
        headers: {
            "Content-Type": "application/json"
        },
        body: body,
    };
    return response;
};

const convertRssIntoJson = (rssFeed) => {
    console.log(rssFeed);
    return new Promise((res, rej) => {
        feed.load(rssFeed, (err, rss) => {
            if (err) {
                console.log("Error: ${err}");
                return rej(err)
            }
            console.log(rss)
            return res(rss)
        });
    })
};

Если вы хотите узнать больше об асинхронности/ await, вы можете увидеть это в здесь .

EDIT : рефакторинг кода и код, добавленный для решения 1)

...