thenableFactory.js 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. module.exports = function() {
  2. function isThenable(obj) {
  3. return obj && (obj instanceof Object) && typeof obj.then==="function";
  4. }
  5. function resolution(p,r,how) {
  6. try {
  7. /* 2.2.7.1 */
  8. var x = how ? how(r):r ;
  9. if (p===x) /* 2.3.1 */
  10. return p.reject(new TypeError("Promise resolution loop")) ;
  11. if (isThenable(x)) {
  12. /* 2.3.3 */
  13. x.then(function(y){
  14. resolution(p,y);
  15. },function(e){
  16. p.reject(e)
  17. }) ;
  18. } else {
  19. p.resolve(x) ;
  20. }
  21. } catch (ex) {
  22. /* 2.2.7.2 */
  23. p.reject(ex) ;
  24. }
  25. }
  26. function _unchained(v){}
  27. function thenChain(res,rej){
  28. this.resolve = res;
  29. this.reject = rej;
  30. }
  31. function Chained() {};
  32. Chained.prototype = {
  33. resolve:_unchained,
  34. reject:_unchained,
  35. then:thenChain
  36. };
  37. function then(res,rej){
  38. var chain = new Chained() ;
  39. try {
  40. this._resolver(function(value) {
  41. return isThenable(value) ? value.then(res,rej) : resolution(chain,value,res);
  42. },function(ex) {
  43. resolution(chain,ex,rej) ;
  44. }) ;
  45. } catch (ex) {
  46. resolution(chain,ex,rej);
  47. }
  48. return chain ;
  49. }
  50. function Thenable(resolver) {
  51. this._resolver = resolver ;
  52. this.then = then ;
  53. };
  54. Thenable.resolve = function(v){
  55. return Thenable.isThenable(v) ? v : {then:function(resolve){return resolve(v)}};
  56. };
  57. Thenable.isThenable = isThenable ;
  58. return Thenable ;
  59. } ;