Uncaught (in promise) ReferenceError: setImmediate is not defined at Object.exports.delay (index.js? [sm]:5876) at StreamHelper.resume (index.js? [sm]:5470) at index.js? [sm]:5430 at new Promise (<anonymous>) at _accumulate (index.js? [sm]:5413) at StreamHelper.accumulate (index.js? [sm]:5458) at ZipObject.async (index.js? [sm]:6241) at index.js? [sm]:3536 at Array.forEach (<anonymous>) at Helloworld.loadMiniGameZipConfig (index.js? [sm]:3535)
报错代码
1 2 3 4 5 6 7 8 9 10
/** * Defer the call of a function. * @param {Function} callback the function to call asynchronously. * @param {Array} args the arguments to give to the callback. */ exports.delay = function(callback, args, self) { setImmediate(function () { callback.apply(self || null, args || []); }); };
报错分析
我们同事在官方库的 Issues 内看到了连个讨论
帖子一:generateAsync not work and no error thrown on v3.10.0 and v3.10.1#864
帖子二: JSZip v3.10+ breaks in some sandboxed browser environment because dependency setimmediate breaks #909
var nextHandle = 1; // Spec says greater than zero var tasksByHandle = {}; var currentlyRunningATask = false; var doc = global.document; var registerImmediate;
functionsetImmediate(callback) { // Callback can either be a function or a string if (typeof callback !== "function") { callback = newFunction("" + callback); } // Copy function arguments var args = newArray(arguments.length - 1); for (var i = 0; i < args.length; i++) { args[i] = arguments[i + 1]; } // Store and register the task var task = { callback: callback, args: args }; tasksByHandle[nextHandle] = task; registerImmediate(nextHandle); return nextHandle++; }
functionrunIfPresent(handle) { // From the spec: "Wait until any invocations of this algorithm started before this one have completed." // So if we're currently running a task, we'll need to delay this invocation. if (currentlyRunningATask) { // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a // "too much recursion" error. setTimeout(runIfPresent, 0, handle); } else { var task = tasksByHandle[handle]; if (task) { currentlyRunningATask = true; try { run(task); } finally { clearImmediate(handle); currentlyRunningATask = false; } } } }
functioncanUsePostMessage() { // The test against `importScripts` prevents this implementation from being installed inside a web worker, // where `global.postMessage` means something completely different and can't be used for this purpose. if (global.postMessage && !global.importScripts) { var postMessageIsAsynchronous = true; var oldOnMessage = global.onmessage; global.onmessage = function() { postMessageIsAsynchronous = false; }; global.postMessage("", "*"); global.onmessage = oldOnMessage; return postMessageIsAsynchronous; } }
functioninstallPostMessageImplementation() { // Installs an event handler on `global` for the `message` event: see // * https://developer.mozilla.org/en/DOM/window.postMessage // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
var messagePrefix = "setImmediate$" + Math.random() + "$"; var onGlobalMessage = function(event) { if (event.source === global && typeof event.data === "string" && event.data.indexOf(messagePrefix) === 0) { runIfPresent(+event.data.slice(messagePrefix.length)); } };
functioninstallReadyStateChangeImplementation() { var html = doc.documentElement; registerImmediate = function(handle) { // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. var script = doc.createElement("script"); script.onreadystatechange = function () { runIfPresent(handle); script.onreadystatechange = null; html.removeChild(script); script = null; }; html.appendChild(script); }; }
// If supported, we should attach to the prototype of global, since that is where setTimeout et al. live. var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global); attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
// Don't get fooled by e.g. browserify environments. if ({}.toString.call(global.process) === "[object process]") { // For Node.js before 0.9 installNextTickImplementation();
} elseif (canUsePostMessage()) { // For non-IE10 modern browsers installPostMessageImplementation();
} elseif (global.MessageChannel) { // For web workers, where supported installMessageChannelImplementation();
/** * Defer the call of a function. * @param {Function} callback the function to call asynchronously. * @param {Array} args the arguments to give to the callback. */ exports.delay = function(callback, args, self) { setTimeout(function () { callback.apply(self || null, args || []); },0); };