我试图从onreadystatechange AJAX调用中返回一个值...我找到了这个页面:stackoverflow link。我虽然让它工作但是意识到添加或删除fn功能没有区别。以下代码有效:
username_is_available();
function username_is_available() {
var username = document.getElementById('username').value;
get_data('username', username, function(returned_value) {
if (returned_value == 'true') {
document.getElementById('username_err').innerHTML = 'Taken';
} else {
document.getElementById('username_err').innerHTML = 'Available';
};
});
}
function get_data(data_type, data, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText);
}
};
xmlhttp.open("GET", "availability.php?" + data_type + "=" + data, true);
xmlhttp.send();
}
一切正常,但这不是我的目标,我想要一个函数username_is_available(),如果用户名确实可用,则返回true。 相反,在这里我发生了一个动作(innerHTML被改变了)。如果我尝试在匿名函数中返回,我会得到相同的结果,就像我从onreadystatechange中直接返回它一样:var unasigned
答案 0 :(得分:3)
不幸的是,由于确定是否采用用户名的过程是异步的,因此无法从函数调用中返回true
或false
的值。您可以做的是使用专门为此目的设计的语言功能,设置类似于您现在所拥有的内容(回调)。
Promise是其中一项功能。
用法看起来大致如下:
function username_is_available(username) {
return new Promise(resolve => {
get_data("username", username, resolve);
});
}
function get_data(data_type, data, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText == "true");
}
};
xmlhttp.open("GET", "availability.php?" + data_type + "=" + data, true);
xmlhttp.send();
}
// Usage:
username_is_available("Ivan").then(available => {
let text = available ? "Available" : "Taken";
document.getElementById("username_err").innerHTML = text;
});
这取决于availablity.php
返回true
和false
作为文本,在调用resolve
之前将其转换为布尔值。
将来,当ES7 + async
和await
指令可用时,使用promise就会这么简单(请注意 {{1} } 关键字):
await
编辑:如果你不能使用ES6或承诺,那就回到了好的回调!
let available = await username_is_available("Ivan");
let text = available ? "Available" : "Taken";
document.getElementById("username_err").innerHTML = text;
答案 1 :(得分:0)
我一直在玩观察员作为承诺的替代品。我设置了一个an example in plnkr来展示它是如何工作的。我认为在你的情况下它看起来像这样:
function Producer() {
this.listeners = [];
}
Producer.prototype.add = function(listener) {
this.listeners.push(listener);
};
Producer.prototype.remove = function(listener) {
var index = this.listeners.indexOf(listener);
this.listeners.splice(index, 1);
};
Producer.prototype.notify = function(message) {
this.listeners.forEach(function(listener) {
listener.update(message);
});
};
var notifier = new Producer;
function get_data(data_type, data) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
notifier.notify(xmlhttp.responseText);
}
};
xmlhttp.open("GET", "availability.php?" + data_type + "=" + data, true);
xmlhttp.send();
}
var username_is_available = {
update: function(returned_value) {
var username = document.getElementById('username').value;
if (returned_value == 'true') {
document.getElementById('username_err').innerHTML = 'Taken';
} else {
document.getElementById('username_err').innerHTML = 'Available';
};
}
}
notifier.add(username_is_available);
get_data("username", username);
注意Producer
代码是可重用的,您可以为其他ajax / observable请求创建一个新实例。