2017-02-08 12 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" 
    } 
}