我在ext js.file上有一个xhr函数,它将值发送到休息服务并期望回复。 我在点击事件btn上调用此函数。它第一次响应“未定义”,然后当我再次触发按钮时,它会以正确的值响应。我几乎可以肯定我的反应不是即时的,但为什么函数不能等到它有值然后将它指向我的返回值,而不是发送给我未定义。
var b;
function Transport(parameters, Page) {
var http = new XMLHttpRequest();
http.open("POST", "http://***.***.***.***/" + Page, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", parameters.length);
http.onreadystatechange = function() { //Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
b = http.response;
}
}
http.send(parameters);
return b;
}
页面上函数的调用
var transaction = Transport(parameters,"/mypage.php");
alert(transaction);
答案 0 :(得分:3)
您正在发出异步请求,但尝试同步处理结果。相反,请使用回调。
function transport(parameters, Page, callback) { // not a constructor, cammel case
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://***.***.***.***/" + Page);
//Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// don't set content-length, you'll get a warning
xhr.addEventListener('load', function () {
callback(this.response, this);
});
xhr.send(parameters);
return xhr;
}
然后
transport(
parameters,
"/mypage.php",
function (response) {alert(response);}
);
在ES6中,我们可以将其写为Promise
/**
* Fetches a resource using XMLHttpRequest and a Promise
* @param {String} url - The URL of the resource to get
* @param {String|FormData|Blob|File} [postData] - Any data to POST
* @param {String} [responseType] - The type of response to expect (defaults to document)
* @returns {Promise}
*/
function fetch(url, postData, responseType) {
return new Promise((res, rej) => {
var x = new XMLHttpRequest();
x.responseType = responseType || 'document';
x.addEventListener('load', e => res(x.response, x));
x.addEventListener('error', e => {
console.warn('XHR Error', url, e);
rej(x.response, x);
});
if (!postData) {
x.open('GET', url);
x.send();
} else {
x.open('POST', url);
if ('string' === typeof postData)
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.send(postData);
}
});
}
然后
fetch(Page, parameters, 'text').then(alert);
答案 1 :(得分:1)
您正尝试在异步模式下使用httprequest。 http.send()立即返回。您可以尝试使用Asynch的代码为False。
var b;
function Transport(parameters,Page) {
var http = new XMLHttpRequest();
http.open("POST", "http://***.***.***.***/"+Page, false);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", parameters.length);
http.send(parameters);
b=http.response;
return b;
}
请参阅http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp了解详情。
答案 2 :(得分:0)
当您致电Transport()发送请求时,b
已存在并且值为undefined
。该调用是异步的,因此立即返回,而不等待请求完成。该请求仍在后台处理,并在您第二次按下该按钮时完成。完成后,设置b,由第二次调用返回。
如果您将代码更改为以下内容,行为将更像您所期望的那样:
function doSomethingWithMyData(data) {
...
}
function Transport(parameters, page) {
var http = new XMLHttpRequest();
http.open("POST", "http://***.***.***.***/" + page, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", parameters.length);
http.onreadystatechange = function() { //Call a function when the state changes.
function() {
if(http.readyState == 4 && http.status == 200) {
doSomethingWithMyData(http.reponse);
}
}
}
http.send(parameters);
}
...
var transaction = Transport(parameters,"/mypage.php");