函数在分配正确的值之前不等待分配响应
function doesnt wait for response to be assigned before assigning the correct value
我在 ext js.file 上有一个 xhr 函数,它向 rest 服务发送值并期望返回响应。
我在单击事件 btn 上调用此函数。第一次它响应 "undefined" 然后当我再次按下按钮时它以正确的值响应。我几乎可以肯定我的响应不是即时的,但为什么函数不能等到它有值然后将它分配给我的 return 值,而不是发送给我未定义的值。
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);
当您调用 Transport() 发送请求时,b
已经存在并具有值 undefined
。该调用是异步的,因此 returns 立即调用,无需等待请求完成。该请求仍在后台处理,并在您第二次点击按钮时完成。当它完成时它设置 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");
您正在尝试在异步模式下使用 httprequest。其中 http.send() returns 立即。您可以尝试使用 Asynch to 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。
您正在发出 异步 请求,但试图 同步 处理结果。相反,使用回调。
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);
我在 ext js.file 上有一个 xhr 函数,它向 rest 服务发送值并期望返回响应。 我在单击事件 btn 上调用此函数。第一次它响应 "undefined" 然后当我再次按下按钮时它以正确的值响应。我几乎可以肯定我的响应不是即时的,但为什么函数不能等到它有值然后将它分配给我的 return 值,而不是发送给我未定义的值。
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);
当您调用 Transport() 发送请求时,b
已经存在并具有值 undefined
。该调用是异步的,因此 returns 立即调用,无需等待请求完成。该请求仍在后台处理,并在您第二次点击按钮时完成。当它完成时它设置 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");
您正在尝试在异步模式下使用 httprequest。其中 http.send() returns 立即。您可以尝试使用 Asynch to 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。
您正在发出 异步 请求,但试图 同步 处理结果。相反,使用回调。
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);