Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // maybe that can compose graphql api?
- /*
- Using Es6 Proxies, I created an object that can resolve promises from a chained object accessor pattern.
- simply await the values, or supply a callback to .then() and watch the magic.
- */
- Symbol.queue = Symbol("queue"); //using Symbols to hide properties from being used or altered
- Symbol.data = Symbol("data");
- function Promiser( obj ) {
- return new Proxy(obj, {
- get(target, prop){
- var new_prop = false;
- if(prop == "then" && this[Symbol.queue]){ //if "then" is accessed, and there is something in the queue
- let resolve = this[Symbol.queue];
- let promise = resolve[1]((data)=>{
- let obj = this[Symbol.data] //resolved data from last promise
- obj[resolve[0]] = data;
- return new Promise((res,rej)=>{
- this[Symbol.data] = {}; //erase data
- delete this[Symbol.queue];//erase queue
- res(obj);//resolve then
- if(obj)
- Object.assign(target, obj ); //Assign resolved values to the proxy target, so that promise wont have to be called again.
- })
- });
- let then = promise.then.bind(promise);
- return then;
- }
- let promise;
- if(target[prop] instanceof Promise == false && prop !== "then"){ //if the prop is not "then" or a promise. (a real value)
- if(this[Symbol.queue]){ //if there is a queue
- let resolve = this[Symbol.queue], obj = this[Symbol.data];
- promise = resolve[1]((data)=>{ //resolve last promise
- obj[resolve[0]] = data;
- return new Promise((res,rej)=>{ //create immediately resolving promise with value
- res(target[prop])
- })
- });
- promise = promise.then.bind(promise); //bind to keep this
- }else{
- promise = new Promise((res,rej)=>{ //else simply create a new promise with value
- res(target[prop])
- })
- promise = promise.then.bind(promise);
- }
- }
- if(this[Symbol.queue]){ //if it is a promise and there is a queue
- let resolve = this[Symbol.queue], obj = this[Symbol.data];
- promise = resolve[1]((data)=>{ //resolve last promise
- obj[resolve[0]] = data;
- return target[prop]; //return this promise
- });
- promise = promise.then.bind(promise); //bind
- }
- else if (!promise) {
- this[Symbol.data] = {}; //if there after all the alternations, there is still no promise, erase the data. start from scratch.
- promise = target[prop].then.bind(target[prop]);
- }
- this[Symbol.queue] = [ prop, promise ]; //supply the promise and the property.
- //all alternations ensure that no matter what the value, a promise is always given which must be resolved.
- return new Proxy(target, this);
- }
- })
- }
- var obj = Promiser({
- a: new Promise((res,rej)=>setTimeout(()=>res(1), 1300)),
- b: new Promise((res,rej)=>setTimeout(()=>res(2), 1300)),
- c: new Promise((res,rej)=>setTimeout(()=>res(3), 1300)),
- d:1,
- e:2,
- f:3,
- });
- 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