JavaScript:在 AWS Lambda 节点应用程序中将 RSS 转换为 JSON

JavaScript: Converting RSS into JSON in AWS Lambda Node app

我目前正在 AWS Lambda 上编写函数。我想将 RSS 提要转换为 JSON 并在发送到 Lambda 端点时将其作为正文中的响应给出。

我正在使用 npm package 将 RSS 转换为 JSON。但是,当我运行代码。我看到我在 RSS URL 的转换中未定义。这是以下代码:

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

但是,在 console.log(rssAsJsonData) 时,我在日志中得到 undefined

但是,在调试时,当我将正文更改为 body: json.stringify("TESTING") 时,我能够看到 console.log(rss) 正常工作

但是,它仅在登录到控制台时有效,而在我尝试将其传递给主体时无效 body: body, 我似乎找不到错误是什么。对于这个项目,我从 Ruby 移动到 JavaScript 可能我遗漏了一些东西。

我正在使用 Postman 拨打电话:

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

你在 convertRssIntoJson 中的 rss 对象还没有任何值,因为到目前为止还没有填充回调。这就是您的 undefined 的来源。

默认情况下,回调本身不会使代码异步,但 NodeJS 使用非阻塞 IO 模型,并且由于 feed.load 是 IO 调用,它将异步执行。

你现在有几个选项,但我只会列出两个。一个不太好的解决方案:

1) 修复它的不太好的方法是将回调作为参数添加到您的 convertRssIntoJson 函数并将该 rss 对象的值向上游传递。不太好的完整代码可以在下面找到:

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 承诺。

所以您的客户端代码现在很简单:

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

想了解更多async/await,可以在here.

中查看

编辑:为解决方案 1)

添加代码重构和代码