Created
January 26, 2020 18:45
-
-
Save XoseLluis/fdb379421cb6648dbd1331370f82eb34 to your computer and use it in GitHub Desktop.
Proxying sync and async methods
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let calculator = { | |
simpleCalculation(n){ | |
return 25 * n; | |
}, | |
complexCalculation(n){ | |
return new Promise(res => { | |
setTimeout(() => res(44 * n), 3000) | |
}); | |
}, | |
//mainly the same as the above | |
async complexCalculation2(n){ | |
let res = await new Promise(res => { | |
setTimeout(() => res(44 * n), 3000) | |
}); | |
return res; | |
} | |
} | |
let proxiedCalculator = new Proxy(calculator, { | |
get: function(target, property, receiver){ | |
let it = target[property]; | |
if (typeof it !== "function"){ | |
return it; | |
} | |
return function(){ | |
console.log("before invoking"); | |
//we're not trapping additional calls done from this method, so we invoke the original method via "target" rather than via "this" | |
let result = target[property](...arguments); | |
//same as the above: | |
//let result = it.call(target, ...arguments); | |
if (result instanceof Promise){ | |
return result.then(res => { | |
console.log("after completion of async function"); | |
return res; | |
}); | |
} | |
else{ | |
console.log("after completion of sync function"); | |
return result; | |
} | |
}; | |
} | |
}); | |
//THE BELOW APPROACH IS WRONG, it won't work properly for synchronous methods | |
let wronglyProxiedCalculator = new Proxy(calculator, { | |
get: function(target, property, receiver){ | |
let it = target[property]; | |
if (typeof it !== "function"){ | |
return it; | |
} | |
//I can not do it like this, cause with the async I would be returning a Promise in both cases, so for the invoker of a sync function he gets a promise of X rathern than X, so that's not what he's expecting | |
return async function(){ | |
//I'm not trapping additional calls done from this object | |
console.log("before invoking"); | |
let result = target[property](...arguments); | |
//it.call(target, ...arguments); | |
if (result instanceof Promise){ | |
let resolvedResult = await result; | |
console.log("after completion of async function"); | |
return resolvedResult; | |
} | |
else{ | |
console.log("after completion of sync function"); | |
return result; | |
} | |
}; | |
} | |
}); | |
(async () => { | |
let result = proxiedCalculator.simpleCalculation(2); | |
console.log(result); | |
result = await proxiedCalculator.complexCalculation(2); | |
console.log(result); | |
console.log("- doing it the wrong way now:"); | |
result = wronglyProxiedCalculator.simpleCalculation(2); | |
console.log(result); | |
//it prints: Promise { 50 } | |
//rather than 50 | |
result = await wronglyProxiedCalculator.complexCalculation(2); | |
console.log(result); | |
})(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment