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

标签 javascript json aws-lambda rss rss-reader

我目前正在 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) 时,我得到了 undefinedenter image description here

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

但是,它仅在登录到控制台时有效,而在我尝试将其传递给正文时无效 body: body, 我似乎找不到错误是什么。我正在为这个项目从 Ruby 转向 JavaScript,也许我遗漏了一些东西。

我正在使用 Postman 进行调用: enter image description here

最佳答案

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 Promise。

因此您的客户端代码现在非常简单:

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) 添加代码重构和代码

关于JavaScript:在 AWS Lambda 节点应用程序中将 RSS 转换为 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54874403/

相关文章:

php - 从过程代码转向oop

amazon-web-services - 解决 AWS Lambda 500MB/tmp 存储限制

javascript - 为什么我获取不到这个 d3.js 文本的 Bounding Box?

c# - asp.net-mvc: js 文件中的 razor '@' 符号

javascript - 将 this.unblock() 与 Meteor percolate 一起使用 :synced-cron

node.js - 如何从 Alexa Skill 获取 Amazon Echo 的位置

python - 如何解析复制对象请求的 Boto3 200 响应

javascript - Anime.js backgroundColor 给出意想不到的结果

json - 关于extends的Go JSON命名策略

用于解析 JSON 结果的 C# 类