sails.js 控制器从承诺中获取数据
sails.js controller get data from a promise
我正在尝试使用 sails.js(使用 node.js)。
我有一个控制器如下。 Thsi 控制器将在 url 参数中传递的 ical url 解析为 ical_url
我正在尝试解析它并根据我的需要构建一个规范化的 json objetc。我有一个 parse
函数
那只暴露在这个控制器之外。使用 node-ical npm 包 (https://www.npmjs.com/package/node-ical)
解析 ical 内容。在 ical.fromURL
方法中,我有一个回调函数,我用它
初始化一个变量 normalized_data
并在其中存储数据。我打算使用该数据
并调用 decorate
方法进行一些处理并取回 json。请
查看以 //>>>>>>
开头的行,按照我的意愿,我无法访问 normalized_data
根据 https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87 ical.fromURL
正在返回一个承诺
但我很难理解如何使用该承诺中的数据。
有人可以帮我在这个文件中进行所需的更改(尤其是在 parse
方法中)以
符合我的期望吗?提前致谢。
/**
* IcalsController
*/
const ical = require('node-ical');
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat'];
function normalize(ev_obj) {
return {
"uid": ev_obj.uid,
"start": ev_obj.start.toDateString(),
"end": ev_obj.end.toDateString(),
"start_ts": ev_obj.start,
"end_ts": ev_obj.end,
"user": ev_obj.organizer.val.split("mailto:")[1].split("@")[0], //TODO - use regex for extraction
"summary": ev_obj.summary,
"categories": ev_obj.categories,
"all_day": (ev_obj["event-allday"] == "true")
}
}
function decorate(data) {
//do something here and return a json object
//return json_object;
}
module.exports = {
parse: function (req, res) {
if (req.param("ical_url") == undefined) {
return res.status(400).send("ical_url is missing");
}
ical.fromURL( //refer - https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87
req.param("ical_url"),
{},
function (err, data) {
let normalized_data = [];
for (let k in data) {
if (data.hasOwnProperty(k)) {
if (data[k].type == 'VEVENT') {
normalized_data.push(normalize(data[k]));
}
}
}
}
);
//>>>>>> Here I want to call decorate function and pass normalized_data as parameter
let result = decorate(normalized_data)
return res.send(result);
},
};
问题是由于没有考虑 fromURL
方法的异步性质。
代码正在调用fromURL
,这将导致在将来某个时间方法完成时调用回调,然后立即尝试发送尚未收到的数据作为响应给客户。
您需要在异步操作完成并且您实际收到一些数据后发送响应,更像这样:
parse: function (req, res) {
if (req.param("ical_url") == undefined) {
return res.status(400).send("ical_url is missing");
}
ical.fromURL( //refer - https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87
req.param("ical_url"),
{},
function (err, data) {
let normalized_data = [];
for (let k in data) {
if (data.hasOwnProperty(k)) {
if (data[k].type == 'VEVENT') {
normalized_data.push(normalize(data[k]));
}
}
}
res.send(decorate(normalized_data)); << Response moved inside the callback.
}
);
}
虽然我实际上会建议,但您可以使用 async/await
关键字作为更简洁的解决方案。
parse: async function (req, res) { << Mark method as async
if (req.param("ical_url") == undefined) {
return res.status(400).send("ical_url is missing");
}
// Await keyword lets us use data from a promise more like it were simpler synchronous code
const raw_data= await ical.fromURL( //refer - https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87
req.param("ical_url"),
{});
let normalized_data = [];
// Do your normalization of raw_data here
return res.send(decorate(noramlized_data));}
我正在尝试使用 sails.js(使用 node.js)。
我有一个控制器如下。 Thsi 控制器将在 url 参数中传递的 ical url 解析为 ical_url
我正在尝试解析它并根据我的需要构建一个规范化的 json objetc。我有一个 parse
函数
那只暴露在这个控制器之外。使用 node-ical npm 包 (https://www.npmjs.com/package/node-ical)
解析 ical 内容。在 ical.fromURL
方法中,我有一个回调函数,我用它
初始化一个变量 normalized_data
并在其中存储数据。我打算使用该数据
并调用 decorate
方法进行一些处理并取回 json。请
查看以 //>>>>>>
开头的行,按照我的意愿,我无法访问 normalized_data
根据 https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87 ical.fromURL
正在返回一个承诺
但我很难理解如何使用该承诺中的数据。
有人可以帮我在这个文件中进行所需的更改(尤其是在 parse
方法中)以
符合我的期望吗?提前致谢。
/**
* IcalsController
*/
const ical = require('node-ical');
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat'];
function normalize(ev_obj) {
return {
"uid": ev_obj.uid,
"start": ev_obj.start.toDateString(),
"end": ev_obj.end.toDateString(),
"start_ts": ev_obj.start,
"end_ts": ev_obj.end,
"user": ev_obj.organizer.val.split("mailto:")[1].split("@")[0], //TODO - use regex for extraction
"summary": ev_obj.summary,
"categories": ev_obj.categories,
"all_day": (ev_obj["event-allday"] == "true")
}
}
function decorate(data) {
//do something here and return a json object
//return json_object;
}
module.exports = {
parse: function (req, res) {
if (req.param("ical_url") == undefined) {
return res.status(400).send("ical_url is missing");
}
ical.fromURL( //refer - https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87
req.param("ical_url"),
{},
function (err, data) {
let normalized_data = [];
for (let k in data) {
if (data.hasOwnProperty(k)) {
if (data[k].type == 'VEVENT') {
normalized_data.push(normalize(data[k]));
}
}
}
}
);
//>>>>>> Here I want to call decorate function and pass normalized_data as parameter
let result = decorate(normalized_data)
return res.send(result);
},
};
问题是由于没有考虑 fromURL
方法的异步性质。
代码正在调用fromURL
,这将导致在将来某个时间方法完成时调用回调,然后立即尝试发送尚未收到的数据作为响应给客户。
您需要在异步操作完成并且您实际收到一些数据后发送响应,更像这样:
parse: function (req, res) {
if (req.param("ical_url") == undefined) {
return res.status(400).send("ical_url is missing");
}
ical.fromURL( //refer - https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87
req.param("ical_url"),
{},
function (err, data) {
let normalized_data = [];
for (let k in data) {
if (data.hasOwnProperty(k)) {
if (data[k].type == 'VEVENT') {
normalized_data.push(normalize(data[k]));
}
}
}
res.send(decorate(normalized_data)); << Response moved inside the callback.
}
);
}
虽然我实际上会建议,但您可以使用 async/await
关键字作为更简洁的解决方案。
parse: async function (req, res) { << Mark method as async
if (req.param("ical_url") == undefined) {
return res.status(400).send("ical_url is missing");
}
// Await keyword lets us use data from a promise more like it were simpler synchronous code
const raw_data= await ical.fromURL( //refer - https://github.com/jens-maus/node-ical/blob/HEAD/index.js#L87
req.param("ical_url"),
{});
let normalized_data = [];
// Do your normalization of raw_data here
return res.send(decorate(noramlized_data));}