承诺总是待定(语法错误?)

时间:2017-02-08 12:16:58

标签: javascript node.js npm es6-promise

我对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()函数返回它。您可以在评论中找到结果。

有没有人知道会出现什么问题?

感谢您的帮助,请善待......我还是个菜鸟! ; - )

2 个答案:

答案 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"
    }
}