Deferred设计image.png

image.png

image.png
和ES6的Promise很像,设计灵感来自Deferred对象。
image.png

代码实现如下:

  1. var wait = function() {
  2. var deferred = $.Deferred();
  3. console.log(deferred);
  4. var test = function() {
  5. console.log('开车了!');
  6. deferred.resolve('Max');
  7. }
  8. setTimeout(test, 2000);
  9. return deferred;
  10. }
  11. $.when(wait())
  12. .done(function() {
  13. console.log('done');
  14. })
  15. .fail(function() {
  16. console.log('fail');
  17. });
  1. jQuery.extend({
  2. // 异步回调解决方案
  3. Deferred: function(func) {
  4. var tuples = [
  5. ["resolve", "done", jQuery.callbacks("once memory"), "resolved"],
  6. ["reject", "fail", jQuery.callbacks("once memory"), "rejected"],
  7. ["notify", "progress", jQuery.callbacks("memory")],
  8. ];
  9. var deferred = {};
  10. var state = 'pending';
  11. var promise = {
  12. state: function() {
  13. return state;
  14. },
  15. then: function() { // done, fail, progress
  16. },
  17. promise: function(obj) {
  18. return obj != null ? jQuery.extend(obj, promise) : promise;
  19. }
  20. };
  21. tuples.forEach(function(tuple, i){
  22. var list = tuple[2];
  23. var stateString = tuple[3];
  24. // promise[done, fail, progress] = list.add
  25. promise[tuple[1]] = list.add;
  26. if(stateString) {
  27. list.add(function() {
  28. state = stateString;
  29. });
  30. }
  31. deferred[tuple[0]+'With'] = list.fire;
  32. // deferred [resolve, reject, notify]
  33. deferred[tuple[0]] = function() {
  34. deferred[tuple[0] + 'With'](this === deferred ? promise : this, arguments);
  35. return this;
  36. };
  37. });
  38. // make deferred as a promise
  39. promise.promise(deferred);
  40. return deferred;
  41. },
  42. when: function(obj) {
  43. return obj.promise();
  44. }
  45. });