Javascript 如何等待另一个 JS 加载以继续操作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8618464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to wait for another JS to load to proceed operation?
提问by mvbl fst
I have an issue. One of my JS scripts needs Facebook SDK and Twitter widgets JS to load first. Facebook creates FB
object, Twitter creates twttr
object. Both of them create these objects AFTER my script fires, even though they're loaded from <head>
.
我有一个问题。我的一个 JS 脚本需要首先加载 Facebook SDK 和 Twitter 小部件 JS。Facebook 创建FB
对象,Twitter 创建twttr
对象。他们都在我的脚本触发后创建这些对象,即使它们是从<head>
.
I think solution is to periodically check if FB and twttr are defined, and then proceed with executing my script. But I have no idea how to do this.
我认为解决方案是定期检查是否定义了 FB 和 twttr,然后继续执行我的脚本。但我不知道该怎么做。
I tried creating a loop
我尝试创建一个循环
while (typeof FB === 'undefined' || typeof twttr === 'undefined' || typeof twttr.widgets === 'undefined') {
// run timeout for 100 ms with noop inside
}
But this clearly does not work as it keeps firing timeouts at a high speed and page hangs.
但这显然不起作用,因为它不断以高速触发超时并且页面挂起。
Please help me, I can't sleep because of this issue.
请帮帮我,我因为这个问题睡不着。
回答by Wayne
If the scripts are loaded in the normal, synchronousway, then just make sure that your<script>
include appears afterthe library scripts in the document's <head>
. If, on the other hand, those scripts are loading objects asynchronously(as seems to be the case), then create something like this:
如果脚本以正常的同步方式加载,那么只需确保您的<script>
包含出现在文档的<head>
. 另一方面,如果这些脚本正在异步加载对象(似乎是这种情况),则创建如下内容:
function whenAvailable(name, callback) {
var interval = 10; // ms
window.setTimeout(function() {
if (window[name]) {
callback(window[name]);
} else {
window.setTimeout(arguments.callee, interval);
}
}, interval);
}
And use it like this:
并像这样使用它:
whenAvailable("twttr", function(t) {
// do something
});
The function given in the second argument to whenAvailable
will not execute until twttr
is defined on the global window
object. You can do the same thing for FB
.
在第二个参数中给出的函数在全局对象上定义whenAvailable
之前不会执行。您可以对.twttr
window
FB
Important note:Those libraries probably also provide some built-in way to execute code afterthey have loaded. You should look for such hooks in their respective documentation.
重要提示:这些库可能还提供了一些在加载后执行代码的内置方式。你应该在它们各自的文档中寻找这样的钩子。
回答by Filip Roséen - refp
Have you put your script to be executed on page load? (ie. body onload="do_this ();"
)
你有没有把你的脚本在页面加载时执行?(即。body onload="do_this ();"
)
That should make your code execute once all external resources has been loaded.
一旦加载了所有外部资源,这应该使您的代码执行。
Regarding the use of setTimeout
关于setTimeout的使用
setTimeout
will return immediately, if you'd like to wait for certain variable to be defined, use something as the below.
setTimeout
将立即返回,如果您想等待某个变量被定义,请使用以下内容。
function when_external_loaded (callback) {
if (typeof FB === 'undefined' || typeof twtter === 'undefined') {
setTimeout (function () {
when_external_loaded (callback);
}, 100); // wait 100 ms
} else { callback (); }
}
...
when_external_loaded (function () {
alert (FB);
alert (twtter);
});
回答by jfriend00
If the Facebook scripts are being loaded asynchronously, Facebook has a supported way to execute code when it's library loads which should be much more efficient than polling for it. See this answer for an example: https://stackoverflow.com/a/5336483/816620.
如果 Facebook 脚本是异步加载的,Facebook 有一种受支持的方式在库加载时执行代码,这应该比轮询效率高得多。以这个答案为例:https: //stackoverflow.com/a/5336483/816620。
If the Facebook scripts are being loaded synchronously, then you don't have to wait for them - they will load before any other scripts after them run.
如果 Facebook 脚本正在同步加载,那么您不必等待它们 - 它们将在运行后的任何其他脚本之前加载。
回答by ?ukasz Sto
const checkIfLoaded = ('lib', cb) => {
const interval = setInterval(() => {
if (lib) {
typeof cb === 'function' && cb();
clearInterval(interval);
} else {
console.log('not yet');
}
}, 100);
}