javascript 中異步方法的單元測試和Promise

作為一個后端開發(fā)人員, 由于公司項目的需要. 最近開始轉(zhuǎn)向javascript.
由于我司一向秉承TDD(測試驅(qū)動開發(fā)) 和100% 覆蓋率的開發(fā)原則. 所以在做js 開發(fā)的時候, 免不了要對js 代碼進行單元測試.
普通的js 代碼還好, 但是遇到異步代碼( 如timers.setTimeout(callback)). 由于我司項目的特殊性, 并不能引入第三方的測試框架. 而只能使用原生的js 方法和特性來進行單元測試. 也就是我們的單元測試框架和assert 庫都是自己重寫的.

最后發(fā)現(xiàn)老馬的一篇文章 Testing Asynchronous JavaScript. 介紹了相關的方法.

總體的思路: mock 掉異步調(diào)用callback 的方法, 改為直接對callback 進行立即調(diào)用.
例如: 要對ajax 請求進行單元測試, 那么在測試文件中復寫 $.ajax.

 $.ajax = function(ajaxOpts) {
      var doneCallback = ajaxOpts.done;
      doneCallback(simulatedAjaxResponse);
 };

然后,這篇文章推薦使用Promise 來代替callback 來編寫異步方法. 作為一個后端人員, 又對Promise 進行了一番研究.

Promise

  • 核心思想: 關注點從operation 的調(diào)用轉(zhuǎn)移到處理operation 的結果.

1, Promise

  • 方法的調(diào)用返回promise, 而不是操作的結果.
  • promise 是一種代理, 代表操作的future result.
  • Promise 是對in process 的異步操作的封裝, 可以從方法返回, 傳遞給方法, 存儲在queue 中.
  • jquery 中的deffer 就屬于promise, 這說明promise 解決的是一種帶有延遲的事件, 這個事件會被延遲到未來某個合適點再執(zhí)行.
    • 執(zhí)行過程: 在promise 上注冊callback, 然后當操作完成且結果可用時, 由promise 執(zhí)行callback.

2, Promise 與異步

  • 同步方法的特性: return value && throw exception.
  • Promise 給予異步方法了同步的2個特性. 它規(guī)定方法必須返回一個Promise.
  • Promise 對象有三種狀態(tài):
    • Pending – Promise對象的初始狀態(tài),等到任務的完成或者被拒絕;
    • Fulfilled – 任務執(zhí)行完成并且成功的狀態(tài);
    • Rejected – 任務執(zhí)行完成并且失敗的狀態(tài)
  • Promise 的可選行為:
    • 被一個值填充.
    • 拒絕并附帶exception.
    • 這反映在then 方法接收的兩個回調(diào)函數(shù)上.

3, Then

  • then 不是為了將callbacks 連接到一個聚合集合.
  • 而是在一個Promise 上應用transformation, 并從該轉(zhuǎn)換中產(chǎn)生一個新的promise.

4, Immutable promise

  • 方法必須返回一個新的promise. 這樣將一個promise 分配給多個消費者時,它們的狀態(tài)才不會互相干擾.
    • 當promise 被fulfilled/failed 后,它就是immutable的.
      • promise 的轉(zhuǎn)換, 會有4種情況(2*2, 具體參照第2節(jié)Promise 的可選行為).
      • 而Jquery 的promise 只是簡單地將state mutate到寄存的promise 上.

5, Exception

  • 通過捕獲異常并將其轉(zhuǎn)換為rejection, 同時處理了intentional(throw new Error("bad data"))/unintentional(aFunctionThatDoesNotExist())異常.
    • 異常會冒泡到最近的rejection handler.

6, Promise 規(guī)范

  • Promise 是含有then 方法屬性的對象.
  • 這樣就能在完全不知promise 的實現(xiàn)的情況下, 編寫庫代碼.
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容