gpt4 book ai didi

javascript - 如果函数已经在 statechange - js 上运行,则延迟函数

转载 作者:行者123 更新时间:2023-12-02 17:01:45 25 4
gpt4 key购买 nike

我觉得答案就在那里,但我不知道该查找什么。我研究了 deferpromise 但如果我希望它适用于自身,我不确定如何应用它。

如果 update_content() 正在运行,我不希望在第一次完成之前再次调用它。

History.Adapter.bind(window, 'statechange', function() {

var event_state = History.getState();

// bad pseudo code
if(update_content() is running, wait till it is finished(function() {
update_content(event_state.data.html);
}

});

正如您通过我可怕的伪代码所看到的,我希望它等待运行 update_content()(如果它已经在运行)。一旦完成,它就会再次运行。从淡入/淡出等需要 1-3 秒才能完成,我希望每个状态更改都等到上一个请求完成。

顺便说一句,没有 AJAX。我希望它在这个意义上是同步的。

如何延迟函数运行直到其完成运行?

这是update_content()代码:

// this function updates page content with ajax and cool effects!
function update_content(data) {
if(data == null) return;

var id = $(data).prop('id'),
content = "#" + id,
header = 0;

// if the header is full, header = 0. if it's tiny, header = 1
if($('#navbar.affix').length) { header = 1; }

// if the page that needs to be loaded is NOT on the page
// this could be #main, #content, etc
if(!$(content).length) {
$(data).hide().appendTo('#main_wrapper');
}

// show the homepage $('#main')
// fades the content viewer out. no positioning is done on the homepage.
if(id == "main") {

if(header == 1) { $('body, html').scrollTop(55); } else { window.scrollTo(0,0); }

$('#main').siblings(':visible').center(header); // puts visible content on TOP of page

$('#main')// /.center(header)
.show(); // home page goes behind content
$('#main').siblings().fadeOut(600, function() { // fadeout content overlay, and ON COMPLETE
$(this).hide(); // hide that shit
});
if(header == 1) { $('body, html').scrollTop(55); } else { window.scrollTo(0,0); }

return;

}

// show the content viewer $('#content')
// fades content viewer in
if(id = "content") {

$('#content')
.center(header) // place on top and center
.fadeIn(function() { // fade in, and ON COMPLETE
$('#main').hide(); // quickly remove siblings - DO NOT USE FADE
$(this).uncenter(); // places it static so it is normal

if(header == 1) { $('body, html').scrollTop(55); } else { window.scrollTo(0,0); }
});

return;
}

}

最佳答案

首先,您需要知道 update_content() 何时完成。为此,您可以在两个动画上使用一些 promise ,并返回一个 promise ,当在此函数中启动的任何动画完成时,该 promise 将得到解决(如果没有启动动画,则可以立即解决):​​

// this function updates page content with ajax and cool effects!
// it returns a promise that is resolved when any animations started in this
// function are done
var updateRunning = 0;
function update_content(data) {
if(data == null) [
// return an already resolved promise
return $().promise();
}

++updateRunning;

var id = $(data).prop('id'),
content = "#" + id,
header = 0, p1, p2;

// if the header is full, header = 0. if it's tiny, header = 1
if($('#navbar.affix').length) { header = 1; }

// if the page that needs to be loaded is NOT on the page
// this could be #main, #content, etc
if(!$(content).length) {
$(data).hide().appendTo('#main_wrapper');
}

// show the homepage $('#main')
// fades the content viewer out. no positioning is done on the homepage.
if(id == "main") {

if(header == 1) { $('body, html').scrollTop(55); } else { window.scrollTo(0,0); }

$('#main').siblings(':visible').center(header); // puts visible content on TOP of page

$('#main')// /.center(header)
.show(); // home page goes behind content
p1 = $('#main').siblings().fadeOut(600, function() { // fadeout content overlay, and ON COMPLETE
$(this).hide(); // hide that shit
}).promise();
if(header == 1) { $('body, html').scrollTop(55); } else { window.scrollTo(0,0); }


} else {

// show the content viewer $('#content')
// fades content viewer in
if(id == "content") {

p2 = $('#content')
.center(header) // place on top and center
.fadeIn(function() { // fade in, and ON COMPLETE
$('#main').hide(); // quickly remove siblings - DO NOT USE FADE
$(this).uncenter(); // places it static so it is normal

if(header == 1) {
$('body, html').scrollTop(55);
} else {
window.scrollTo(0,0);
}
}).promise();

}
// note that either p1, p2 or both might be undefined here, but
// $.when() should still work for us
return $.when(p1, p2).always(function() {
--updateRunning;
});
}

仅供引用,我还将 if (id = "content") 更改为 if (id == "content") 因为我认为您遇到的是编码错误.

然后,为您调用的 update_content() 创建一个队列和一个包装器,而不是 update_content,这个包装器的想法是,每当 update_content() 完成后,它会处理下一个排队的项目。您可以通过维护一个标志来判断 update_content() 是否正在运行。

var queue = [];
function update_content_wrapper(data) {
if (updateRunning !== 0) {
// just queue the data if update already running
queue.push(data);
} else {
update_content(data).always(function() {
// if items in the queue, get the oldest one
if (queue.length) {
update_content_wrapper(queue.shift());
}
});
}
}

然后,您只需在 statechange 事件上调用包装函数,它就会为您完成所有脏活:

History.Adapter.bind(window, 'statechange', function() {
var event_state = History.getState();
update_content_wrapper(event_state.data.html);
});

在任何其他地方调用 update_content() 时,都应该将其切换为调用 update_content_wrapper()

关于javascript - 如果函数已经在 statechange - js 上运行,则延迟函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25632004/

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