inexorabletash / polyfill

JavaScript Polyfills, Shims and More
Other
1.36k stars 354 forks source link

Exception: Object Expected when Promises.Then()/Catch() called from WSH #156

Closed Filipus24 closed 5 years ago

Filipus24 commented 5 years ago

I am using the full polyfill.js library inside a WSH script. Note that this script does not run inside a browser, but rather from the command line. I therefore had to comment out all console.assert() statements and also add a var self = global = this in my calling script because self isn't defined in JScript. Everything I tested works, except for Promises. Initializing them works fine, but as soon as I add a .then() or .catch() statement, I get an Object expected exception. When trying to trace the issue (which isn't so easy when you don't have a browser console handy), I realized that the Promise's constructor is called again as soon as the then() or catch() method is fired. That doesn't seem right to me... Here's my code:

var myPromise = new Promise( function(resolve,reject){ resolve("Hello World"); }); myPromise.then(function(msg) { return true; });

Has anyone successfully tried this with JScript/WSH?

Mouvedia commented 5 years ago

setTimeout is probably the culprit. check https://stackoverflow.com/q/2198449/248058

ref https://github.com/inexorabletash/polyfill/blob/master/es6.js#L41

Filipus24 commented 5 years ago

Sir, you are a prince!

I modified the following line:

return function(job) { setTimeout(job, 0); };

to

if(typeof setTimeout === "function"){ return function(job) { setTimeout(job, 0); }; } else { return function(job) { job(); }; }

And everything works fine.

I'm not quite sure why the original code calls setTimeout with a delay value of 0, I can only assume it has something to to with threading, but the change doesn't seem to have an impact on the Jscript implementation since it runs on a single thread.

inexorabletash commented 5 years ago

Promise resolutions do not occur synchronously. They occur in "microtasks", following the current task. In older browsers, using a full "task" via setTimeout was an approximation.