gpt4 book ai didi

javascript - 在 require.js 中覆盖 setTimeout

转载 作者:数据小太阳 更新时间:2023-10-29 04:42:02 26 4
gpt4 key购买 nike

我们在我们的项目中使用 require.js,我们需要覆盖第 705 行的 setTimeout,这是我们需要以某种方式忽略/省略的代码完全设置超时(我的意思是运行它),问题是如果我在更改版本时在开源代码中显式更改它,代码将会丢失,我应该如何从外部仅针对 require.js 文件覆盖此 setTimout 和只要我使用这个库就保留它,是否可以在全局 JS 中以优雅的方式做到这一点?

https://github.com/jrburke/requirejs/blob/master/require.js

这是第 705 行

        //If still waiting on loads, and the waiting load is something
//other than a plugin resource, or there are still outstanding
//scripts, then just try back later.
if ((!expired || usingPathFallback) && stillLoading) {
//Something is still waiting to load. Wait for it, but only
//if a timeout is not already in effect.
if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
checkLoadedTimeoutId = setTimeout(function () {
checkLoadedTimeoutId = 0;
checkLoaded();
}, 50);
}
}

仅供引用,我们这样做的原因是 Chrome: timeouts/interval suspended in background tabs?

最佳答案

您已声明您的目标是解决 Chrome 在 setTimeout 上对后台标签页执行的限制。我不认为这样做是个好主意,但如果你必须这样做,那么你绝对应该给 RequireJS 打补丁,而不是在全局范围内乱用 setTimeout。你说:

if I change it in the open source code explicit when I change version the code will be lost

只有当您没有使用明智的方法来执行更改时,才会出现这种情况。明智地做到这一点是可能的。例如,您可以使用 Gulp 获取安装在 node_modules 中的 require.js 文件(在使用 npm 安装 RequireJS 之后)并生成一个补丁build 中的文件。然后在您的应用程序中使用此修补文件。这是 gulpfile.js:

var gulp = require("gulp");

// Bluebird is a good implementation of promises.
var Promise = require("bluebird");

// fs-extra produces a `fs` module with additional functions like
// `ensureDirAsync` which is used below.
var fs = require("fs-extra");

// Make it so that for each the function in fs that is asynchronous
// and takes a callback (e.g. `fs.readFile`), a new function that
// returns promise is created (e.g. `fs.readFileAsync`).
Promise.promisifyAll(fs);

var to_replace =
"if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {\n\
checkLoadedTimeoutId = setTimeout(function () {\n\
checkLoadedTimeoutId = 0;\n\
checkLoaded();\n\
}, 50);";

var replace_with =
"if (isBrowser || isWebWorker) {\n\
checkLoaded();";


gulp.task("default", function () {
// Use `fs.ensureDirAsync` to make sure the build directory
// exists.
return fs.ensureDirAsync("build").then(function () {
return fs.readFileAsync("node_modules/requirejs/require.js")
.then(function (data) {
data = data.toString();

// We use the split/join idiom to a) check that we get
// the string to be replaced exactly once and b)
// replace it. First split...
var chunks = data.split(to_replace);

// Here we check that the results of splitting the
// chunk is what we expect.
if (chunks.length < 2) {
throw new Error("did not find the pattern");
}
else if (chunks.length > 2) {
throw new Error("found the pattern more than once");
}

// We found exactly one instance of the text to
// replace, go ahead. So join...
return fs.writeFileAsync("build/require.js",
chunks.join(replace_with));
});
});
});

在运行它之前,您需要先运行 npm install gulp fs-extra bluebird requirejs。无论如何,您可以使用 Gulp,您可以使用 Grunt,或者您可以使用您想要执行构建的任何其他系统。重点是:

  1. 您有一个可重现的自动化方法来为 RequireJS 打补丁。如果您使用 npm 安装新版本的 RequireJS,当您重建软件时,补丁是自动应用,只要 RequireJS 的代码没有以阻止应用补丁的方式更改。如果更改阻止应用补丁,请参阅下一点,了解会发生什么。

  2. 此方法比在运行时覆盖 setTimeout 更健壮。假设 James Burke 决定在较新版本的 RequireJS 中重命名 checkLoadedcheckDone 并重命名关联的变量(以便 checkLoadedTimeoutId 变为 checkDoneTimeoutId)。上面的 gulpfile 将在您再次运行时引发异常,因为它找不到要替换的文本。您必须更新要替换的文本和替换,以便补丁与新版本的 RequireJS 一起使用。这样做的好处是您会提前收到警告,告知您情况已发生变化,您需要查看补丁。 游戏后期您不会有惊喜,也许是在您已经向客户交付了新版本的软件之后。

    在运行时覆盖 setTimeout 的方法将默默地无法完成它们的工作。他们将寻找包含 checkLoadedTimeoutId 的函数,该函数在新版本中将不再存在。所以他们只会让 RequireJS 按默认方式运行。失败将是一个微妙的失败。 (我已经使用建议的自定义版本的 setTimeout 运行 RequireJS,该项目在未优化时加载了 50 个以上的模块。我没有看到 RequireJS 使用普通 setTimeout 和 RequireJS 使用自定义 setTimeout。)

  3. 此方法不会减慢每次使用 setTimeout 的速度。 setTimeout 被 RequireJS 以外的其他代码使用。无论您如何削减它,在 setTimeout 的自定义替换中添加代码,开始在传递给它的每个函数中寻找字符串,都将 所有 使用 setTimeout 较慢。

关于javascript - 在 require.js 中覆盖 setTimeout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34587078/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com