我有以下脚本无效:
function getWidgetContent( widget ) {
if(widget.script!=null){
$global_widget_id = widget.widget_id;
$.getScript( "js/" + widget.script, function() {
$( ".widget_header_title_" + widget.widget_id ).append( widget.title );
});
}
}
这称为如下:
for ( j = 0; j <= widget_data.d.length - 1; j++ ) {
getWidgetContent( widget_data.d[j] );
}
我认为这将在函数内运行函数,为全局值赋值,然后在循环的每次迭代中运行$.getScript
。但那并没有发生。它似乎循环遍历循环直到循环结束,让我们说它循环3次,每次为全局值赋值,即3次,然后它最终去$.getScript
。
无法正常工作的现在只会使用$ .getScript文件中的全局值的最后一次分配3次...
如何更改此值以便为全局变量赋值,运行$.getScript
。完成后,继续使用原始循环,将下一个值分配给全局变量,运行$.getScript
直到循环结束。
答案 0 :(得分:1)
getScript方法是异步的,所以在从包含脚本值的服务器获得响应之前,循环运行下一次迭代
这就是为什么我们必须发送一个回调函数。一旦服务器响应,javascript就知道该怎么做。所以虽然普通循环无法帮助我们,但我们可以使用重复函数。
我们得到的回调函数是调用loopFunc然后转移到集合/数组中的下一个项目。
我跳了这个可以给你带来灵感:
var getWidgetContent = function(wiget, loopFunc) {
if(widget.script!=null){
$global_widget_id = widget.widget_id
$.getScript( "js/" + widget.script, function() {
$( ".widget_header_title_" + widget.widget_id ).append( widget.title )
loopFunc() //now we got a response from the server and want to move on to the next script tag.
})
}
}
var i = 0
(function loopFunc(){ //we define a function and call it instantly
if(i < widget_data.d.length){
getWidgetContent(widget_data.d,loopFunc) //now we call the getWidgetContent but we send in the current function aswell
console.log($global_widget_id) // this is going to change each time
i += 1
}
}())
答案 1 :(得分:1)
查看其他人的答案我只能这样做。 更改您的实施:
$.getScript( "js/" + widget.script, function() {
$( ".widget_header_title_" + widget.widget_id ).append( widget.title );
});
到相应的ajax调用,但不是异步
$.ajax({
url: "js/" + widget.script,
dataType: "script",
async: false,
success: function() {
$( ".widget_header_title_" + widget.widget_id ).append( widget.title );
}
});
答案 2 :(得分:1)
getWidgetContent
正在执行getScript
,但getScript
会立即返回,而不是等待网络(与CPU相比相对较慢)完成得到你的脚本。这不是一个bug,而是一个 awesome 的东西 - 使用异步编程,你可以在CPU上完成大量工作,而且你不必等待比CPU慢得多的东西如果你不想!
回答你的问题:
getScripts
一次运行会更快,但如果您真的不能允许第二个getScript
在第一个完成之前启动,请只调用getWidgetContent
一次,然后让你的回调确定下一个小部件并再次使用它来调用getWidgetContent
。答案 3 :(得分:1)
你得到这个是因为$ .getScript是一个异步方法。在这种情况下,这意味着该方法在脚本完成加载之前立即返回,并继续在其后执行代码。
这意味着:
$.getScript('a.js', function () {
console.log('Loaded a');
});
$.getScript('b.js', function () {
console.log('Loaded b');
});
$.getScript('c.js', function () {
console.log('Loaded c');
});
// Output could be:
// Loaded c
// Loaded a
// Loaded b
这意味着所有脚本文件请求可以同时完成,但这也意味着订单不是确定性的(固定)。
如果您使用的是jQuery 1.5及更高版本,则可以通过链接promises来确保顺序调用getWidgetContent
。
但是,这种方法的缺陷在于你不同时加载所有脚本请求,请求将在前一个请求完成后一个接一个地发送。
确保返回$ .getScript的结果Deferred Object(我在这里做了很少的更改,只记下return
语句):
function getWidgetContent( widget ) {
if(widget.script!=null){
$global_widget_id = widget.widget_id;
return $.getScript( "js/" + widget.script, function() {
$( ".widget_header_title_" + widget.widget_id ).append( widget.title );
});
}
return null;
}
在完成上一个承诺后执行新的getWidgetContent的新方法(完成上一个操作):
function doGetWidgetContentAfter(promise, widget) {
return promise.then(function () {
return getWidgetContent( widget );
});
}
致电:
var promise = $.when(true);
for ( j = 0; j <= widget_data.d.length - 1; j++ ) {
promise = doGetWidgetContentAfter( promise, widget_data.d[j] );
}
doGetWidgetContentAfter
所做的是,当所述promise
完成时然后为getWidgetContent
调用widget
函数。 then
方法返回一个在任何内部方法promise完成时完成的promise。
我知道它开始听起来很复杂,但是要玩游戏并尝试它。 :)
答案 4 :(得分:0)
尝试将变量分配给窗口命名空间:
window.global_widget_id = "foo";
然后您可以这样引用它:
var myId = window.global_widget_id;
并覆盖它:
window.global_widget_id = "newId";
(变量赋值中的(不正确。忽略最后一部分。)$
也可能让jQuery感到困惑。)
修改强>
似乎$.getScript()
个文件不属于全局范围:jQuery's getScript - including files into the main scope?。
也许您可以通过回调调用$.getScript()
函数而不是嵌入式document.ready()
,并通过这种方式传递变量?
答案 5 :(得分:0)
可能它可以帮到你, 在循环中放置函数可以重写其中包含的变量
在我看来,这样做:
function getWidgetContent(widget) {
if(w_script != null){
// And make variable for make sure each values come
// from parent function and not from `$.getScript`
var w_script = widget.script;
var w_widget_id = widget.widget_id;
var w_title = widget.title;
$.getScript( "js/" + w_script, function() {
$( ".widget_header_title_" + w_widget_id ).append( w_title );
});
}
}
这个案子面对我,但我在$.ajax
面对它,我试着像上面那样做变量
如果成功,请打电话给我,祝你好运
答案 6 :(得分:0)
如果您不想按顺序执行代码,那么您将不得不重写一下。在前一个调用其回调之前,不应该对getScript
进行下一次调用。这可以通过从回调中调用getWidgetContent
来完成......
类似的东西:
function getWidgetContent(d, index) {
var widget = d[index];
if(widget.script!=null){
$global_widget_id = widget.widget_id;
$.getScript( "js/" + widget.script, function() {
$( ".widget_header_title_" + widget.widget_id ).append( widget.title );
if (index <= d.length - 1)
getWidgetContent(d,index+1); //call the next one
});
}
}
//Start the calls
getWidgetContent( widget_data.d,0);