javascript 中异步方法的单元测试和Promise

作为一个后端开发人员, 由于公司项目的需要. 最近开始转向javascript.
由于我司一向秉承TDD(测试驱动开发) 和100% 覆盖率的开发原则. 所以在做js 开发的时候, 免不了要对js 代码进行单元测试.
普通的js 代码还好, 但是遇到异步代码( 如timers.setTimeout(callback)). 由于我司项目的特殊性, 并不能引入第三方的测试框架. 而只能使用原生的js 方法和特性来进行单元测试. 也就是我们的单元测试框架和assert 库都是自己重写的.

最后发现老马的一篇文章 Testing Asynchronous JavaScript. 介绍了相关的方法.

总体的思路: mock 掉异步调用callback 的方法, 改为直接对callback 进行立即调用.
例如: 要对ajax 请求进行单元测试, 那么在测试文件中复写 $.ajax.

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

然后,这篇文章推荐使用Promise 来代替callback 来编写异步方法. 作为一个后端人员, 又对Promise 进行了一番研究.

Promise

  • 核心思想: 关注点从operation 的调用转移到处理operation 的结果.

1, Promise

  • 方法的调用返回promise, 而不是操作的结果.
  • promise 是一种代理, 代表操作的future result.
  • Promise 是对in process 的异步操作的封装, 可以从方法返回, 传递给方法, 存储在queue 中.
  • jquery 中的deffer 就属于promise, 这说明promise 解决的是一种带有延迟的事件, 这个事件会被延迟到未来某个合适点再执行.
    • 执行过程: 在promise 上注册callback, 然后当操作完成且结果可用时, 由promise 执行callback.

2, Promise 与异步

  • 同步方法的特性: return value && throw exception.
  • Promise 给予异步方法了同步的2个特性. 它规定方法必须返回一个Promise.
  • Promise 对象有三种状态:
    • Pending – Promise对象的初始状态,等到任务的完成或者被拒绝;
    • Fulfilled – 任务执行完成并且成功的状态;
    • Rejected – 任务执行完成并且失败的状态
  • Promise 的可选行为:
    • 被一个值填充.
    • 拒绝并附带exception.
    • 这反映在then 方法接收的两个回调函数上.

3, Then

  • then 不是为了将callbacks 连接到一个聚合集合.
  • 而是在一个Promise 上应用transformation, 并从该转换中产生一个新的promise.

4, Immutable promise

  • 方法必须返回一个新的promise. 这样将一个promise 分配给多个消费者时,它们的状态才不会互相干扰.
    • 当promise 被fulfilled/failed 后,它就是immutable的.
      • promise 的转换, 会有4种情况(2*2, 具体参照第2节Promise 的可选行为).
      • 而Jquery 的promise 只是简单地将state mutate到寄存的promise 上.

5, Exception

  • 通过捕获异常并将其转换为rejection, 同时处理了intentional(throw new Error("bad data"))/unintentional(aFunctionThatDoesNotExist())异常.
    • 异常会冒泡到最近的rejection handler.

6, Promise 规范

  • Promise 是含有then 方法属性的对象.
  • 这样就能在完全不知promise 的实现的情况下, 编写库代码.
    原文作者:沪上最强亚巴顿
    原文地址: https://www.jianshu.com/p/c1117a374331
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞