cujojs / meld

AOP for JS with before, around, on, afterReturning, afterThrowing, after advice, and pointcuts
Other
644 stars 65 forks source link

Meld afterReturn advice is getting called before promise is resolved #45

Closed santhoshsk1918 closed 6 years ago

santhoshsk1918 commented 6 years ago

AfterReturning and After is getting called when promise is in pending State before it reaches fulfilled or rejected State

In my method abc i am calling an other promise waiting for it resolve and then resolve this

// In page service.js
module.exports.abc = (a, b) => {
 return new Promise((resolve, reject) => {
   // This calls a a promise in an other page
     var xyz = xyzDao.getValues();
     xyz.then((response) => {
         console.log("beforeResolve");
         resolve(response);
         console.log("beforeResolve");
     })
  })
}
//In Page MeldService 
var meld = require('meld');
var service = require('service')
let advice = {
    before: function() {
       let joinPointObj = meld.joinpoint()

      console.log("In Before of ",joinPointObj.method) 
    },
  afterReturning: function(returningValue){
       let joinPointObj = meld.joinpoint()
      console.log("In After Returning of ", joinPointObj.method);
      console.log(returningValue);
  }
}

meld(service, ['abc'], advice);

In my logs In Before of abc In After Returning of abc Promise { \<pending> } Before Resolve After Resolve

briancavalier commented 6 years ago

Hi @santhoshsk1918. Meld doesn't provide builtin async advice. That basically means meld doesn't treat promises specially, i.e. the promise (rather than the promise's fulfillment value) is the return value. You can, however build your own async advices on top of the functions meld provides.

Here's a very simple example of how you might implement your own "after fulfilling" advice:

function afterFulfilling (target, method, advice) {
    function applyAfterFulfilling (joinpoint) {
        const resultPromise = joinpoint.proceed()
        return resultPromise
          .then(advice)
          // Then next line prevents advice from changing the return value,
          // while still preserving the promise chain and surfacing errors.
          // Feel free to drop it if you *want* to be able to change the return value.
          .then(() => resultPromise)
    }
    return meld.around(target, method, applyAfterFulfilling)
}

Hope that helps!