Guest User

Untitled

a guest
Feb 17th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.56 KB | None | 0 0
  1. // maybe that can compose graphql api?
  2. /*
  3. Using Es6 Proxies, I created an object that can resolve promises from a chained object accessor pattern.
  4. simply await the values, or supply a callback to .then() and watch the magic.
  5. */
  6.  
  7. Symbol.queue = Symbol("queue"); //using Symbols to hide properties from being used or altered
  8. Symbol.data = Symbol("data");
  9. function Promiser( obj ) {
  10. return new Proxy(obj, {
  11. get(target, prop){
  12. var new_prop = false;
  13. if(prop == "then" && this[Symbol.queue]){ //if "then" is accessed, and there is something in the queue
  14. let resolve = this[Symbol.queue];
  15. let promise = resolve[1]((data)=>{
  16. let obj = this[Symbol.data] //resolved data from last promise
  17. obj[resolve[0]] = data;
  18. return new Promise((res,rej)=>{
  19. this[Symbol.data] = {}; //erase data
  20. delete this[Symbol.queue];//erase queue
  21. res(obj);//resolve then
  22. if(obj)
  23. Object.assign(target, obj ); //Assign resolved values to the proxy target, so that promise wont have to be called again.
  24. })
  25. });
  26. let then = promise.then.bind(promise);
  27. return then;
  28.  
  29. }
  30. let promise;
  31. if(target[prop] instanceof Promise == false && prop !== "then"){ //if the prop is not "then" or a promise. (a real value)
  32. if(this[Symbol.queue]){ //if there is a queue
  33. let resolve = this[Symbol.queue], obj = this[Symbol.data];
  34. promise = resolve[1]((data)=>{ //resolve last promise
  35. obj[resolve[0]] = data;
  36. return new Promise((res,rej)=>{ //create immediately resolving promise with value
  37. res(target[prop])
  38. })
  39. });
  40. promise = promise.then.bind(promise); //bind to keep this
  41. }else{
  42. promise = new Promise((res,rej)=>{ //else simply create a new promise with value
  43. res(target[prop])
  44. })
  45. promise = promise.then.bind(promise);
  46. }
  47. }
  48. if(this[Symbol.queue]){ //if it is a promise and there is a queue
  49. let resolve = this[Symbol.queue], obj = this[Symbol.data];
  50. promise = resolve[1]((data)=>{ //resolve last promise
  51. obj[resolve[0]] = data;
  52. return target[prop]; //return this promise
  53. });
  54. promise = promise.then.bind(promise); //bind
  55. }
  56. else if (!promise) {
  57. this[Symbol.data] = {}; //if there after all the alternations, there is still no promise, erase the data. start from scratch.
  58. promise = target[prop].then.bind(target[prop]);
  59. }
  60. this[Symbol.queue] = [ prop, promise ]; //supply the promise and the property.
  61. //all alternations ensure that no matter what the value, a promise is always given which must be resolved.
  62. return new Proxy(target, this);
  63. }
  64. })
  65. }
  66.  
  67. var obj = Promiser({
  68. a: new Promise((res,rej)=>setTimeout(()=>res(1), 1300)),
  69. b: new Promise((res,rej)=>setTimeout(()=>res(2), 1300)),
  70. c: new Promise((res,rej)=>setTimeout(()=>res(3), 1300)),
  71. d:1,
  72. e:2,
  73. f:3,
  74. });
  75.  
  76.  
  77. console.log( await obj.a.b.c.f.e ); //prints { a:1, b:2, c:3, f:3, e:2 }
Add Comment
Please, Sign In to add comment