Skip to content

Instantly share code, notes, and snippets.

@AimWhy
Forked from jasuperior/Promiser.js
Created March 21, 2022 06:46
Show Gist options
  • Select an option

  • Save AimWhy/142cda37fa7d22ced28d9be96ff03b58 to your computer and use it in GitHub Desktop.

Select an option

Save AimWhy/142cda37fa7d22ced28d9be96ff03b58 to your computer and use it in GitHub Desktop.

Revisions

  1. @jasuperior jasuperior revised this gist Dec 25, 2017. 1 changed file with 21 additions and 27 deletions.
    48 changes: 21 additions & 27 deletions Promiser.js
    Original file line number Diff line number Diff line change
    @@ -3,67 +3,61 @@ Using Es6 Proxies, I created an object that can resolve promises from a chained
    simply await the values, or supply a callback to .then() and watch the magic.
    */

    Symbol.queue = Symbol("queue");
    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){
    console.log(prop, this[Symbol.queue]);
    var new_prop = false;
    if(prop == "then" && this[Symbol.queue]){
    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]
    let obj = this[Symbol.data] //resolved data from last promise
    obj[resolve[0]] = data;
    return new Promise((res,rej)=>{
    this[Symbol.data] = {};
    delete this[Symbol.queue];
    res(obj);
    this[Symbol.data] = {}; //erase data
    delete this[Symbol.queue];//erase queue
    res(obj);//resolve then
    if(obj)
    Object.assign(target, 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(this[Symbol.queue]){
    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)=>{
    promise = resolve[1]((data)=>{ //resolve last promise
    obj[resolve[0]] = data;
    return new Promise((res,rej)=>{
    return new Promise((res,rej)=>{ //create immediately resolving promise with value
    res(target[prop])
    })
    });
    promise = promise.then.bind(promise);
    promise = promise.then.bind(promise); //bind to keep this
    }else{
    console.log("no queue");
    promise = new Promise((res,rej)=>{

    promise = new Promise((res,rej)=>{ //else simply create a new promise with value
    res(target[prop])

    })
    console.log(promise, promise.then)
    promise = promise.then.bind(promise);
    }

    //return target[prop];
    }
    if(this[Symbol.queue]){
    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)=>{
    promise = resolve[1]((data)=>{ //resolve last promise
    obj[resolve[0]] = data;
    return target[prop];
    return target[prop]; //return this promise
    });
    promise = promise.then.bind(promise);
    promise = promise.then.bind(promise); //bind
    }
    else if (!promise) {
    this[Symbol.data] = {};
    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 ];
    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);
    }
    })
    @@ -79,4 +73,4 @@ var obj = Promiser({
    });


    console.log(await obj.a.b.c.f.e); //prints {a:1,b:2,c:3,f:3,e:2}
    console.log( await obj.a.b.c.f.e ); //prints { a:1, b:2, c:3, f:3, e:2 }
  2. @jasuperior jasuperior created this gist Dec 25, 2017.
    82 changes: 82 additions & 0 deletions Promiser.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    /*
    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");
    Symbol.data = Symbol("data");
    function Promiser( obj ) {
    return new Proxy(obj, {
    get(target, prop){
    console.log(prop, this[Symbol.queue]);
    var new_prop = false;
    if(prop == "then" && this[Symbol.queue]){
    let resolve = this[Symbol.queue];
    let promise = resolve[1]((data)=>{
    let obj = this[Symbol.data]
    obj[resolve[0]] = data;
    return new Promise((res,rej)=>{
    this[Symbol.data] = {};
    delete this[Symbol.queue];
    res(obj);
    if(obj)
    Object.assign(target, obj );
    })
    });
    let then = promise.then.bind(promise);
    return then;

    }
    let promise;
    if(target[prop] instanceof Promise == false && prop !== "then"){
    if(this[Symbol.queue]){
    let resolve = this[Symbol.queue], obj = this[Symbol.data];
    promise = resolve[1]((data)=>{
    obj[resolve[0]] = data;
    return new Promise((res,rej)=>{
    res(target[prop])
    })
    });
    promise = promise.then.bind(promise);
    }else{
    console.log("no queue");
    promise = new Promise((res,rej)=>{

    res(target[prop])

    })
    console.log(promise, promise.then)
    promise = promise.then.bind(promise);
    }

    //return target[prop];
    }
    if(this[Symbol.queue]){
    let resolve = this[Symbol.queue], obj = this[Symbol.data];
    promise = resolve[1]((data)=>{
    obj[resolve[0]] = data;
    return target[prop];
    });
    promise = promise.then.bind(promise);
    }
    else if (!promise) {
    this[Symbol.data] = {};
    promise = target[prop].then.bind(target[prop]);
    }
    this[Symbol.queue] = [ prop, promise ];
    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}