0

I am trying to refactor jQuery promises with native promise for the below codes.

public functionA(){
    const dArray = Array<JQueryDeferred<{a:string}>>=[];
    //other lines of logic
    functionB(dArray, /*other parameters*/);

}

private functionB(dArray : Array<JQueryDeferred<{a:string}>>[], /*other arguments*/){
    //other lines of logic
    for(var i=0;i<10;i++){
        dArray.push($.Deferred());
        var ele = dArray.length-1;

        functionC(dArray[ele], /*other parameters*/)
            .done((result: { a:string}) => {
                // logic
            })
            .always() => {
                // some additional logic
        });
    }
}

private functionC(d: JQueryDeferred<{a:string}>):JQueryDeferred<{a:string}>{
        if(){//some condition

           // some other logic 
           d.resolve({ a: "completed" });

        }
    return d;
}

As the above methods involved passing deferred objects to multiple functions and array of deferred objects, just seeking help of any better method to rewrite the above with native promise like below;

public functionA(){
    const pArray = Array<Promise<{a:string}>>=[];
    //other lines of logic
    functionB(pArray, /*other parameters*/);

}

private functionB(pArray : Array<Promise<{a:string}>>[], /*other arguments*/){
    //other lines of logic
    for(var i=0;i<10;i++){
        pArray.push((new Promise<{ a:string; }>(resolve => resolvePromise = resolve)););
        var ele = pArray.length-1;

        functionC(pArray[ele], /*other parameters*/)
            .then((result: { a:string }) => {
                // logic
            })
            .finally() => {
                // some additional logic
        });
    }
}

private functionC(p: Promise<{a:string}>):Promise<{a:string}>{
        if(){//some condition
           // some other logic 
           // i am stuck here..
           p.resolve({ a: "completed"}) //no such resolve method to call
           // tried with Promise.resolve({ a: "completed"}), 
           // but my question - will it resolve same way as the index based 
           // resolve like the jQuery deferred version?

        }
    return p;
}

Thanks in advance.

Itsme
  • 67
  • 4
  • `functionA` does not appear to do anything with `dArray`, so why have it at all? – Bergi Jan 10 '23 at 17:52
  • What's up with the `doneFunction`? – Bergi Jan 10 '23 at 17:54
  • @Bergi its a callback function – Itsme Jan 10 '23 at 19:13
  • Yeah, that's what the name sounds like, but why does a promise fulfill with a callback function? Where/when is it supposed to be called, and what will it do? This is a weird pattern. It might help if you could post your actual code, not pseudocode. – Bergi Jan 10 '23 at 20:27
  • Simplified the code for better understanding – Itsme Jan 10 '23 at 22:19
  • Thanks, but it's still not clear what the `dArray`/`pArray` is going to be used for. – Bergi Jan 10 '23 at 23:32
  • They are array of promises, used to resolve or reject based on execution result of some other business logics or when a particular condition is met. Basic intention is to have a proper implementation - how to return the correct array index resolve/reject when native promise array is used, like the ones with its equivalent Jquery based implementation. – Itsme Jan 10 '23 at 23:54
  • You mean there is actual business logic in `functionA` that uses the array after it has been filled by `functionB`? – Bergi Jan 10 '23 at 23:58

1 Answers1

0

Promises are not callbacks that you pass into a function. Promises are result values that you return from a function. They are constructed inside the function, and resolved by the logic inside the function only. Unlike a Deferred, they cannot be resolved by anyone who gets a hand on them.

From this approach, the correct code follows:

public functionA() {
    // other lines of logic
    const pArray = functionB(/* other arguments */);
}

private functionB(/* other parameters */): Array<Promise<{a:string}>> {
    //other lines of logic
    const promises: Array<Promise<{a:string}>> = [];
    for (var i=0; i<10; i++) {
        promises.push(
            functionC(/* … */).then((result: { a:string }) => {
                // logic
            }).finally() => {
                // some additional logic
            })
        );
    }
    return promises;
//  ^^^^^^^^^^^^^^^
}

private functionC(): Promise<{a:string}> {
    return new Promise<{ a:string; }>((resolve, reject) => {
//  ^^^^^^^^^^^^^^^^^^
        if (/* some condition */) {
           // some other logic 
           resolve({ a: "completed"});
        } else {
           reject(new Error());
        }
    });
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Sorry I cannot keep the entire functionC results in promise array inside functionB. As I mentioned earlier, i was looking to resolve or reject individual promises in functionC on each iteration in functionB! – Itsme Jan 12 '23 at 12:57
  • Yes you can, and you should. `functionC` *does* resolve or reject an individual promise that is part of the array. Again, please edit your question to show your actual code if you think you cannot apply the solution. – Bergi Jan 12 '23 at 13:00