我有一個文件,tst.html
與內容:JavaScript(Vanilla,no jQuery) - 具有* synchronous的函數* AJAX(XMLHttpRequest)調用的行爲與async相同?
part two
(無標記或其他任何東西,只是爲了演示)
,然後加載所述文件,通過同步 AJAX( XMLHttpRequest
):
function someFunc() {
var str = 'part one_';
var x = new XMLHttpRequest();
x.open('GET', 'tst.html', false); // "false" for synchronous
x.onreadystatechange = function() {
if(x.readyState === 4) {
switch(x.status) {
case 200:
str += x.responseText.trim();
break;
default:
return ''; // Or something
break;
}
}
}
x.send();
str += '_part three';
return str;
}
調用好玩ction:
alert(someFunc());
// Returns "part one_part two_part three"
這是所需的行爲。
但如果我把AJAX調用到它自己的功能:
function ajaxCall() {
var x = new XMLHttpRequest();
x.open('GET', 'tst.html', false);
x.onreadystatechange = function() {
if(x.readyState === 4) {
switch(x.status) {
case 200:
return x.responseText.trim();
break;
default:
return '';
break;
}
}
}
x.send();
}
function someFunc() {
var str = 'part one';
str += ajaxCall();
str += 'part three';
return str;
}
然後調用它:
alert(someFunc());
// Returns "part one_undefined_part three"
函數返回聯軍字符串AJAX有機會完成之前,這與其異步表兄弟的行爲相同。
我一直在尋找沿着「同步AJAX功能」的東西,但是沒有任何東西可以用於任何用途。
AJAX調用的最終用例位於函數的遞歸集合內部,其進一步處理依賴於AJAX返回。類似:
function one(url) {
var x = new XMLHttpRequest();
x.open('GET', url, false);
x.onreadystatechange = function() {
return two(x.responseText.trim());
}
x.send();
}
function two(str) {
var output;
output += stuff;
// ... parse through str
// ... until match found
if(isURL(match)) { // If `match` is a URL
output += one(match);
}else if(isFormattedString(match)) { // if `match` is a string
output += two(match);
}
output += more stuff;
// More processing of output
return output;
}
var final = one(url);
在上面的例子:
- 系統總是與URL啓動(
one(url)
) one()
返回一個字符串,其本身爲two(str)
開口參數
在
two()
內,解析器可能遇到以下任一種:另一個URL或
一個可解析的字符串。
取決於哪個是,兩個功能中的一個被稱爲
- 的輸出被添加到系統中的最終結果
one()
從一個回調將不起作用在這一點上,因爲我仍然需要在two()
之內有最後的return
。
function one(url, callback) {
// ... AJAX stuff
{
callback(two(x.responseText));
}
}
function two(str) {
// ... same as previous
// The following doesn't work, because then `two()` no longer has a `return`
// ... and any other code (i.e. for !isURL cases) will still continue to execute
if(isURL(match)) {
one(match, function(result) {
output += result;
// ... more processing
return output;
});
}else if(...) {
// ... same as previous
}
// ... more stuffs
}
我發現的唯一的另一件事是deferred
,但我不能確定它如何與這個工作,要麼。
有沒有一種方法可以強制JavaScript像對待其他同步函數一樣對待它,其中執行代碼會停止,直到函數完成爲止?我不清楚它爲什麼還沒有,AJAX請求特別聲明爲異步。
在此先感謝。
你的函數'ajaxCall'不返回任何東西 - 相當於'return undefined' - 你需要從函數返回一些東西(不是onreadystate回調) –
同步ajax調用真的不是一個好主意 - 如果服務器有問題會怎樣? JavaScript線程將等待直到服務器響應,並且頁面將完全不響應用戶。同步ajax永遠不會有好的例子。不要使用它。 – Simba
我會建議嘗試使用「承諾」(整潔的東西)。在Jamiec的回答中發佈的鏈接中給出了一個簡要的解釋,否則在MDN中查看:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise – Winter