[英]How can I take advantage of callback functions for asynchronous XMLHttpRequest?
我目前正在编写JavaScript并且对回调感到困惑。 我发现它不是一种内置函数,但......
我现在正在阅读O'Relly JavaScript第5版,它显示的示例代码如下所示:
getText = function(url, callback) // How can I use this callback?
{
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
callback(request.responseText); // Another callback here
}
}
request.open('GET', url);
request.send();
}
基本上,我认为我不理解callback
的一般概念......有人可以写一个示例代码来利用上面的callback
吗?
回调非常简单和漂亮! 由于AJAX调用的性质,在请求结束之前,您不会阻止脚本的执行(这将是同步的)。 回调只是一个指定处理响应的方法,一旦它返回到您的方法。
由于javascript方法是第一类对象,因此可以像变量一样传递它们。
所以在你的例子中
getText = function(url, callback) // How can I use this callback?
{
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
callback(request.responseText); // Another callback here
}
};
request.open('GET', url);
request.send();
}
function mycallback(data) {
alert(data);
}
getText('somephpfile.php', mycallback); //passing mycallback as a method
如果您执行上述操作,则表示您将mycallback
作为处理响应(回调)的方法传递。
编辑
虽然这里的示例没有说明回调的正确好处(您可以简单地将警报放在onReadyStateChange函数中!),但可重用性肯定是一个因素。
你必须记住,重要的是JS方法是第一类对象。 这意味着您可以像对象一样传递它们并将它们附加到各种事件中。 当事件触发时,将调用附加到这些事件的方法。
当你执行request.onreadystatechange = function(){}
你只是在适当的事件触发时分配要调用的方法。
所以这里很酷的是这些方法可以重复使用。 假设您有一个错误处理方法,该方法会弹出警报,并在AJAX请求中的404情况下填充HTML页面中的某些字段。
如果你不能分配回调或传递方法作为参数,你必须一遍又一遍地编写错误处理代码,但是你只需要将它作为一个回调分配,你的所有错误处理都将被排序一气呵成。
首先,我建议阅读回调的内容。 这是一个开始。
回调在异步编程中广泛使用。 如果您不希望在(可能)长时间运行的操作完成之前阻塞,则解决问题的方法之一是将操作委派给将为您执行此操作的人员。 这提出了一个问题:您将如何判断操作何时完成,以及如何获得结果?
一种解决方案是将工作委托给其他人,并且不时地从正常工作中抽出一些时间来问“我给你做的工作了吗?”。 如果是这样,请以某种方式获得结果,然后离开。 问题解决了。
这种方法的问题在于它不会让您的生活更轻松。 你现在被迫每隔一段时间就会问一次,你不会知道操作是否已经完成(但只有下次你记得要问)。 如果您忘记提问,将永远不会收到通知。
更好的解决方案是回调:委派工作时,提供一个功能。 实际完成工作的代码然后承诺在工作完成后立即调用该函数。 你现在可以忘记所有这些东西,并且知道当工作完成后,你的回调将被调用。 不久,不迟。
在这种特定情况下, callback
是一种函数,您可以将getText
作为允许它与您通信的方式提供。 你实际上在说“为我做这项工作,当你完成后,这里有一个功能让你打电话让我知道”。
事实上, getText
选择仅在XMLHttpRequest
(XHR)完成时使用此回调,同时它“让你知道”它也会传递HTTP响应的内容(因此你可以对这些信息采取行动)。
但是花点时间阅读代码。 它为request.onreadystatechange
存储的价值是多少? request.onreadystatechange
的目的是什么?
答案是request.onreadystatechange
可以用来填充回调 。 实际上,XHR为您提供了一种为其提供回调的方法,并且只要底层HTTP请求的状态发生变化,它就会“回拨”。
getText
是一个在其上构建抽象的函数:它在其中插入自己的回调(匿名函数 - 我将其称为“内部” )并接受来自您的另一个回调(参数 - 我'将其称为“外部” )。 当内部回调(记住:每当状态改变时被调用)检测到状态为“完成”(值4
的含义)并且HTTP响应状态代码为200(表示“OK”)时,它调用让你( getText
的用户)知道结果的外部回调。
我希望我有道理。 :)
我个人更喜欢使用Event Listener而不是回调。
使用Listener非常方便,尤其是当您愿意一次处理多个异步请求时。
用法如下(摘自https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest )
function reqListener () {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send()
以正确的“回调”方式工作的是定义一个返回这样的承诺的服务!
$http.head("url2check").then(function () {
return true;
}, function () {
return false;
});
在控制器中使用服务:
<service>.<service method>.then(function (found)) {
if (found) {......
}
@jon是正确的称它为异步!
XMLHttpRequest回调函数和文件上传数据数组
function HttpPost(url, arr, cb, form){
if (form === undefined) { var data = new FormData(); }else{ var data = new FormData(form); }
if (arr !== undefined) {
for (const index in arr) {
data.append(index, arr[index]);
}
}
var hr = new XMLHttpRequest();
hr.onreadystatechange=function(){
if (hr.readyState==4 && hr.status==200){
if( typeof cb === 'function' ){ cb(hr.responseText); }
}
}
hr.upload.onprogress = function(e) {
var done = e.position || e.loaded, total = e.totalSize || e.total;
console.log('xhr.upload progress: ' + done + ' / ' + total + ' = ' + (Math.floor(done/total*1000)/10) + '%');
};
hr.open("POST",url,true);
hr.send(data);
}
// HttpPost callback
function cb_list(res){
console.log(res);
var json = JSON.parse(res);
console.log(json.id + ' ' + json.list);
// loop
for (var objindex in json.list){
console.log(json.list[objindex].id);
}
}
样品:
var data = [];
data["cmd"] = "get-cos";
var form = $('#form')[0];
HttpPost('/api-load', data, cb_list, form);
<form id="form" method="POST" enctype="multipart/form-data">
<input type="file" name="file[]" multiple accept="image/*">
</form>
Http标题内容
hr.setRequestHeader("Content-Type", "application/json");
// data:
var json = {"email": "hey@mail.xx", "password": "101010"}
var data = JSON.stringify(json);
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// data:
var data = "fname=Henry&lname=Ford";
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.