我有一个单页Web应用程序。它的某些行为依赖于修改页面的一部分,然后在修改页面后调用一些函数来格式化该部分(MathJax是我需要做的最重要的修改后调用之一)。
由于Ajax是异步的,所以有时候我没有得到想要的效果,因为我会得到未格式化的页面,因为脚本会在页面内容准备就绪之前运行,为了解决这个问题,我开始用XMLHttpRequest().open()
调用false
以使其同步,并在调用脚本之前确保页面内容已准备就绪。
但这会使页面发出警告
“不赞成在主线程上使用同步XMLHttpRequest,因为它 对最终用户的体验产生不利影响。”
尽管行为正是我所需要的。我不喜欢依靠不赞成使用的行为,因为它现在可能会起作用,但是如果他们改变并破坏了它,则需要两个月的时间,我不得不重新格式化整个代码,并以另一种方式再次解决问题。>
我应该如何处理此警告,如果以后的网络更新可能会破坏该警告,我该怎么办?
编辑: JS代码:
function changeSection(section, page, button, sync=true)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
$(section).empty();
$(section).append(this.responseText);
clearButtons();
setButton(button);
}
};
xhttp.open("GET", page, sync);
xhttp.send();
}
function setLagrange() {
path = MathLog_path + "modelling/lagrange_interpolation.html";
changeSection("#VolatileSection", path, "lagrange_button", false);
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
答案 0 :(得分:2)
我应该如何担心这个警告,
合理地。 :-)告诉您这是不好的做法,其原因是:它会对用户体验产生负面影响。
...我应该怎么做?
只需继续使用异步ajax,并在完成处理程序中调用需要调用的函数即可。
如果使用XHR:
const xhr = new XMLHttpRequest();
xhr.addEventListener("load", () => {
// Call your functions here
});
xhr.addEventListener("error", () => {
// Handle errors here
});
xhr.open("GET", "/path/to/the/resource");
xhr.send();
...但是我会使用fetch
:
fetch("/path/to/the/resource")
.then(response => {
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.appropriateMethodToReadBodyHere();
})
.then(data => {
// Call your functions here
})
.catch(error => {
// Handle errors here
});
...甚至在async
function中也可能:
try {
const response = await fetch("/path/to/the/resource");
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
const data = await response.appropriateMethodToReadBodyHere();
// Call your functions here
} catch (error) {
// Handle errors here
}
您添加了一些代码。这是一个最小的变化示例:
function changeSection(section, page, button, sync=true, callback = () => {})
// *** ------------------------------------------------^^^^^^^^^^^^^^^^^^^^^
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
$(section).empty();
$(section).append(this.responseText);
clearButtons();
setButton(button);
callback(); // ***
}
};
xhttp.open("GET", page, sync);
xhttp.send();
}
function setLagrange() {
path = MathLog_path + "modelling/lagrange_interpolation.html";
changeSection("#VolatileSection", path, "lagrange_button", false, () => {
// *** ---------------------------------------------------------^^^^^^^^^
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
});
//^^^ ***
}
...但是当您使用ES2015 +功能时,我将使用fetch
并从changeSection
返回承诺:
function changeSection(section, page, button, sync=true)
{
return fetch(page)
.then(response => {
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.text(); // or .json() or whatever
})
.then(() => {
$(section).empty();
$(section).append(this.responseText);
clearButtons();
setButton(button);
});
}
function setLagrange() {
path = MathLog_path + "modelling/lagrange_interpolation.html";
changeSection("#VolatileSection", path, "lagrange_button", false).then(() => {
// *** ----------------------------------------------------------^^^^^^
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
});
}
或使用async
函数:
async function changeSection(section, page, button, sync=true)
{
const response = await fetch(page);
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
await response.text(); // or .json() or whatever
$(section).empty();
$(section).append(this.responseText);
clearButtons();
setButton(button);
}
async function setLagrange() {
path = MathLog_path + "modelling/lagrange_interpolation.html";
await changeSection("#VolatileSection", path, "lagrange_button", false);
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
请注意,setLagrange
必须从async
函数中调用,否则必须明确使用其承诺:
setLagrange(/*...*/)
.catch(error => {
// Handle error
});