2017-02-08 15 views
0

我几乎是新的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()函数返回它。你可以在评论中找到结果。

有没有人有一个想法可能会出错?

感谢您的帮助,请善待我......我仍是一名新秀! ;-)

+3

可以最大限度地减少示例代码以更简洁说明问题?我不认为我们需要看到两个屏幕的SQL查询... – deceze

回答

2

问题出在调用get_tagsthen回调中。由于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; 
    } 
) 

它可以只被完全删除(替换为刚那)在最后)。 。

一对夫妇的其他诉未成年人笔记:

  • 你不需要()周围的参数为箭头的功能,如果有只是一个参数(当然,你可能更喜欢一致性的问题风格)
  • 箭头函数的简洁形式通常很方便(例如上面显示的示例,通过result.length > 1过滤结果)。

以下是我想在回答的开头写块,FWIW:

// ... 
) 
.then(data => Promise.all(data.map(entry => get_tags(entry.id)))) 
.then(data => data.filter(result => result.length > 1)) 
// ... 

...但它的风格问题,并在一定程度上甚至什么调试器的问题你倾向于使用,因为有些人比其他人更擅长处​​理这样的单行。

+1

首先:非常感谢您的时间和所有的建议。它帮助我变得更好,并学习思考如何工作。我将执行代码并查看它的运行方式。竖起大拇指!!! –

0

所以我实施了你的代码,当然它有效。但不知何故,我没有设法将您的代码与我的数组注入集成。这是我的结果让数组填充标签元素中的标签。也许你有更好更短的解决方案?

.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" 
    } 
}