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

时间:2019-02-25 20:45:29

标签: javascript json aws-lambda rss rss-reader

我目前正在努力在AWS Lambda上编写函数。我想将RSS feed转换为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;
  });
};

但是,当undefined时,我在日志中得到console.log(rssAsJsonData)enter image description here

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

但是,它仅在登录到控制台时有效,而在我尝试将其传递到正文body: body,时却无效,我似乎找不到错误所在。我正在为该项目从Ruby迁移到JavaScript,也许我错过了一些东西。

我正在使用Postman拨打电话: enter image description here

1 个答案:

答案 0 :(得分:2)

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可与非阻塞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)
        });
    })
};

如果您想了解有关异步/等待的更多信息,可以在here中查看。

EDIT :针对解决方案1)的代码重构和代码添加