我对node.js,express和ES6几乎是新手,但试图抓住它。我写了这段代码,试图实现整洁干净的ES6驱动功能和承诺。但我对继承的函数和值有问题,特别是next()。所以这是我目前编写的代码:
let get_tags = (id) => {
var id = id;
return database.connection(
(connection) => {
return connection.query(
`SELECT
t.name
FROM
wp_terms AS t
INNER JOIN
wp_term_taxonomy AS tt ON tt.term_id = t.term_id
INNER JOIN
wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id
WHERE
tt.taxonomy IN ('post_tag') AND tr.object_id IN (${id})
ORDER BY t.name ASC`
)
}
).then(
(rows) => {
return rows;
}
)
}
router.get('/:city', (req, res, next) => {
switch (req.params.city) {
case 'neanderland':
var post_type = 'neanderland',
title = 'Hauptmeldungen',
region = 'Neanderland';
break;
case 'wuelfrath':
var post_type = 'wuelfrath',
title = 'Hauptmeldungen',
region = 'Wülfrath';
break;
case 'mettmann':
var post_type = 'mettmann',
title = 'Hauptmeldungen',
region = 'Mettmann';
break;
case 'haan':
var post_type = 'haan',
title = 'Hauptmeldungen',
region = 'Haan';
break;
case 'nevigestoenisheide':
var post_type = 'neviges-toenisheide',
title = 'Hauptmeldungen',
region = 'Neviges/Tönisheide';
break;
}
database.connection(
(connection) => {
return connection.query(
`SELECT
p.post_title as title,
p.post_author as author,
t.name as category,
p.ID as id,
p.post_date as date,
p.post_content as text,
p.post_excerpt as excerpt,
p.post_status as status,
p.post_name as slug_url,
pm1.meta_value as hero_thumb_id,
pm2.meta_value as hero_thumb_url
FROM
wp_posts p
LEFT JOIN
wp_postmeta pm1
ON (
pm1.post_id = p.id
AND pm1.meta_value IS NOT NULL
AND pm1.meta_key = "_thumbnail_id"
)
LEFT JOIN
wp_postmeta pm2
ON (
pm1.meta_value = pm2.post_id
AND pm2.meta_key = "_wp_attached_file"
AND pm2.meta_value IS NOT NULL
)
LEFT JOIN
wp_term_relationships tr
ON (
p.ID = tr.object_id
)
LEFT JOIN
wp_term_taxonomy tt
ON (
tr.term_taxonomy_id = tt.term_taxonomy_id
)
LEFT JOIN
wp_terms t
ON (
tt.term_id = t.term_id
)
WHERE
p.post_status="publish"
AND p.post_type="${post_type}"
AND tt.taxonomy = "category"
GROUP BY p.ID
ORDER BY
p.post_date DESC
LIMIT 100`
)
}
).then(
(rows) => {
var posts = [];
rows.forEach(
(element, index, array) => {
var arr = {
id : element.id,
paywall : element.text.includes('[not-level-free-user]'),
date : Date.parse(element.date).format("c"),
title : element.title,
excerpt : element.excerpt,
text : convert_text(element.text),
category : convert_category(element.category),
region : region,
author : convert_author(element.author),
slug : element.slug_url,
tags : '',
media : {
heroid : element.hero_thumb_id,
heroslug: element.hero_thumb_url
}
}
posts.push(arr);
}
);
return posts;
}
).then(
(data) => {
var arr = [];
data.forEach(
(element, index, array) => {
var id = element.id;
var item = get_tags(id).then(
(result) => {
if (result.length >= 1) {
// console.log(result) at this position returns e.g.
// [ RowDataPacket { name: 'Feuerwehr' },
// RowDataPacket { name: 'Nachwuchs' },
// RowDataPacket { name: 'Werbung' } ]
return result;
}
}
)
// console.log(item) at this position returns
// Promise { <pending> }
arr.push(item);
}
);
return arr;
}
).then(
(data) => {
res.json(data)
}
);
});
一切正常,直到倒数第二()。它只返回数组的空元素。似乎get_tags(id)没有保存下一个结果。我在特定位置做了一个控制台日志,但是我找不到错误...我想将get_tags的结果保存到arr变量中,以便为下面的next()函数返回它。您可以在评论中找到结果。
有没有人知道会出现什么问题?
感谢您的帮助,请善待......我还是个菜鸟! ; - )
答案 0 :(得分:2)
问题出在调用then
的{{1}}回调中。由于get_tags
是异步调用,因此您需要等待这些承诺完成,这可以通过get_tabs
轻松完成。
在这里尝试保持你的风格:
Promise.all
旁注:之前的// ...
).then(
(data) => {
// Map the data to promises and return a promise that waits for them
return Promise.all(data.map(
(element, index, array) => {
var id = element.id;
return get_tags(id);
}
));
}
// Now we use a new `then` to filter the data now we have it
).then(
(data) => {
return data.filter(
(result) => {
return result.length > 1;
}
);
}
)
// ...
没有用处:
then
它可以完全删除(最后只用).then(
(rows) => {
return rows;
}
)
替换)。
其他几个小调:
)
参数附近的箭头函数(当然,你可能更喜欢一致的风格)()
过滤结果的示例)。以下是我在答案开头写下块的方法,FWIW:
result.length > 1
...但这是一个风格问题,在某种程度上甚至是你倾向于使用什么调试器的问题,因为有些人比其他人更善于处理这样的单行。
答案 1 :(得分:0)
所以我实现了你的代码,它当然有效。但不知何故,我没有设法将您的代码与我的阵列注入集成。这是我的结果,让数组填充tag元素中的标记。也许你有更好更短的解决方案?
.then(
(data) => {
var test = data;
return Promise.all(
data.map(
(element, index, array) => {
var id = element.id;
return get_tags(id);
}
)
).then(
data => {
data.forEach(
(element, index, array) => {
var tag = [];
element.forEach(
(element, index, array) => {
tag.push(element.name);
}
);
test[index].tags = tag;
}
);
return test;
}
);
}
)
我想要的结果(专注于“标签”):
{
"id": 123456,
"paywall": true,
"date": "2017-01-24T15:02:38.000Z",
"title": "This is a headline",
"excerpt": "This is an excerpt",
"text": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"category": "main",
"region": "city",
"author": "John Johnson",
"slug": "this-is-a-headline",
"tags": [
"Tag1",
"Tag2",
"Tag3"
],
"media": {
"heroid": "123456",
"heroslug": "2017/02/heroimage.jpg"
}
}