Node js開發中的那些旮旮角角 第一部

yellow超發表於2018-05-03

#前戲

上一週是我到現公司來最忙碌的(最有意思的)一週了,為什麼這麼說呢?因為專案中需要提供服務端對使用者病人資訊的一個彙總並以email的形式分享資訊的介面,在幾天的時間裡調研處理一套實施方案。我們服務端是Node.js實現的(其中的npm中有很多豐富的第三方庫來解放你重新造輪子的尷尬)

###配方 pug->html-pdf->pdf2png->s3->sendgrid

#pug 中在phantom中字型無效的解決方案 在開發pug時遇到一個比較棘手的問題,設計定的字型在瀏覽器上是有效果的,但是通過Phantom.js(伺服器端的 JavaScript API 的 WebKit)進行網頁截圖時,字型卻都使用了預設字型,後來只有通過自定義字型檔案才解決這個問題。

style.
        @font-face {
            font-family: CustomFont;
            src: url('./views/fonts/HelveticaNeue.otf');
        }


        .gender {
            display: inline;
            color: rgb(102, 102, 102);
            font-family: CustomFont;
        }
複製程式碼

嗯,模板檔案算是搞定了,接下來就是具體程式碼的實現了。

準備資料材料

要做某件事情肯定都會先把需要的材料先搞到手把!(感覺程式設計和現實生活中解決問題的思路很多都是想通的)

我是受到某人的啟發說通過一個彙總連結串列查詢,把N張表的資料都通過一個查詢搞出來,最後把它變成View,也方便服務端的開發,我這麼一聽感覺是很有道理啊,那就做吧(我感覺我執行力好強☺)

在我們的系統有些表的設定是欄位可以方便增加欄位型別,但在查詢時就必須要考慮行轉列,或是列轉行(這在我之前都是未知領域)

select patient_id, max(IF(contact_type = 'email',value,null)) as 'email', max(IF(contact_type = 'address',value,null)) as 'address', group_concat(case when contact_type='mobile' then contacts.value end) as 'mobiles'
  from contacts where contacts.is_deleted = 0 group by patient_id
複製程式碼

max(IF(contact_type = 'email',value,null) 可以將列中符合contact_type='email' 的提出來單獨作為一列;group_concat(case when contact_type='mobile' then contacts.value end) 則可以將多個型別的通過拼接放在一個單元格中。不過最後遇到一個問題,就是無法將多個mobile很好的區分出來。所以只好老實的在Node.js中分批的查詢其中的資料。放一張截圖,肯定能體會出我心中N多的XX馬(留意下檔名)

Paste_Image.png

###分批次取資料 先講解下前提,customDiagnoses和patientDiagnoses表是1->N的關係。

const customDiagnoses = await Promise.all(
            patientDiagnoses.map(item =>
                CustomDiagnosis.findById(item.sourceId)
            )
)
複製程式碼

Promise.all()是需要等待其中的所有的方法都完全處理完後再執行後面的語句

這裡可以補充一個《如何把一個非同步的方法搞成一個看似同步的方法》

    static async exportPDF(html, options, filePath) {
        const promise = new Promise((reslove, reject) => {
            const callback = (err, res) => {
                if (err) {
                    reject(err)
                    return
                }
                reslove(res)
            }
            pdf.create(html, options).toFile(filePath, callback)
        })
        return promise
    }
複製程式碼

Promise顧名思義就是當你達成某種成就了,我就會幫你幹某件事。 寫一個Promise最有變化就是對callback的處理,其他的基本都跟這個差不多,使用Promise也很簡單,直接在呼叫的地方前面加上一個await即可。

有人會問了為什麼要寫Promise啊?Node.js 不是都是有callback的嗎?幹嘛還要我多次一舉?

起始也不完全都要把非同步方法用Promise封裝起來,但是if 你的一個方法中有N個非同步的 && 根據上一個方法的結果來幹下一件事 { 那麼你的程式碼就會變成一個階梯狀,一層巢狀一層,不移維護也不易閱讀 }

最後附上,我心情勞動後,上天也被感動,給力我一個超可愛的喵星人,也要感謝在開發過程支援和幫助我的某某人!!!

![IMG_0395.JPG](http://upload-images.jianshu.io/upload_images/1530185-d6cb759bb8687d07.JPG?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

下部預告,《測試達人帶飛,讓你裝逼讓你吹》

相關文章