Search code examples
javascriptgoogle-chrometampermonkey

Why async code fails in Tampermonkey on Chrome?


This code:

(async ()=>{
    let i=0;
    while (1) {
        await sleep(1);
        console.log(i++);
    }
})();
function sleep(ms){
    return new Promise(function (resolve, reject) {
        setTimeout(()=>{
            resolve();
        },ms);
    })
}

works correctly in browser, but in Tampermonkey userscript fails with:

Uncaught (in promise) TypeError: Cannot convert undefined or null to object
    at eval (userscript.html?id=4ef091f1-f006-441d-bf58-4bd22750f636:24)
    at new Promise (<anonymous>)
    at sleep (userscript.html?id=4ef091f1-f006-441d-bf58-4bd22750f636:23)
    at eval (userscript.html?id=4ef091f1-f006-441d-bf58-4bd22750f636:18)

after nearly 3k iterations.

I think promises don't work correctly in Tampermonkey.

Used chrome 74, Tampermonkey 4.8.41

Any ideas?

Update: The bug is not in promise. This code fails too:

(function() {
    'use strict';

    function doWork(){
        console.log(doWork.i++);
        setTimeout(doWork,1);
    }
    doWork.i=0;
    doWork();

})();

In opera and FF all of it works perfectly.

Update: Infinite loops are only for examples. But it was tested for working and memory leaks in node,chrome, FF. I think, it happens with many(>4k for me) asynchronous calls in one Tampermonkey script. I'll try give some another code without infinite loops soon.


Solution

  • It is Tampermonkey for chrome sandbox bug. (maybe caused by this chrome issue) This code fixes it, untill issue will not be fixed in TM or Chrome. I used another injection method:

    var scriptText=`
        /* some code fails with this bug */
    `;
    var newScript = document.createElement("script");
    var inlineScript = document.createTextNode(scriptText);
    newScript.appendChild(inlineScript);
    document.body.appendChild(newScript);