如何利用异步XMLHttpRequest的回调函数?

Jap*_*boy 23 javascript asynchronous xmlhttprequest callback

我目前正在编写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();
}
Run Code Online (Sandbox Code Playgroud)

基本上,我想我不明白一般的想法callback......有人可以写一个示例代码来利用callback上述优势吗?

Joh*_*hnP 47

回调非常简单和漂亮!由于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
Run Code Online (Sandbox Code Playgroud)

如果您执行上述操作,则表示您mycallback作为处理响应的方法(回调)传递.

编辑

虽然这里的示例没有说明回调的正确好处(您可以简单地将警报放在onReadyStateChange函数中!),但可重用性肯定是一个因素.

你必须记住,重要的是JS方法是第一类对象.这意味着您可以像对象一样传递它们并将它们附加到各种事件中.当事件触发时,将调用附加到这些事件的方法.

当你这样做时,request.onreadystatechange = function(){}你只是在适当的事件触发时指定要调用的方法.

所以这里很酷的是这些方法可以重复使用.假设您有一个错误处理方法,该方法会弹出警报,并在AJAX请求中的404情况下填充HTML页面中的某些字段.

如果你不能指定回调或传递方法作为参数,你必须一遍又一遍地编写错误处理代码,但是你只需要将它作为一个回调分配,你的所有错误处理都将被排序一气呵成.



Jon*_*Jon 17

首先,我建议阅读回调的内容.是一个开始.

大局

回调在异步编程中广泛使用.如果您不希望在(可能)长时间运行的操作完成之前阻塞,则解决问题的方法之一是将操作委派给将在您身边执行此操作的人员.这提出了一个问题:您将如何判断操作何时完成,以及如何获得结果?

一种解决方案是将工作委托给其他人,并且不时地从正常工作中抽出一些时间来问"我给你做的工作了吗?".如果是这样,请以某种方式获得结果,然后离开.问题解决了.

这种方法的问题在于它不会让您的生活更轻松.你现在被迫每隔一段时间就会问一次,你不会知道操作是否已经完成(但只有下次你记得要问).如果您忘记提问,将永远不会收到通知.

更好的解决方案是回调:委派工作时,提供一个功能.实际完成工作的代码然后承诺在工作完成后立即调用该函数.你现在可以忘记所有这些东西,并且知道当工作完成后,你的回调将被调用.不久,不迟.

这里的回调是什么?

在这种特定情况下,callback您提供的功能是getText允许它与您通信的方式.你实际上在说"为我做这项工作,当你完成后,这里有一个功能让你打电话让我知道".

getText事实上,只有当XMLHttpRequest(XHR)完成时才选择使用此回调,同时它"让你知道"它也会传递HTTP响应的内容(因此你可以对这些信息采取行动).

回调和更多的回调,哦,我的!

但是花点时间阅读代码.它存储的价值是request.onreadystatechange多少?是什么目的request.onreadystatechange

答案是,request.onreadystatechange您可以使用回调进行填充.实际上,XHR为您提供了一种为其提供回调的方法,并且只要底层HTTP请求的状态发生变化,它就会"回拨".

getText是一个在其构建抽象的函数:它将自己的回调(一个匿名函数 - 我将其称为"内部")插入其中并接受来自您的另一个回调(参数 - 我将将其称为"外部").当内部回调(记住:每当状态改变时被调用)检测到状态为"已完成"(值的含义4)并且HTTP响应状态代码为200(表示"OK")时,它调用外部回调让你,用户getText,知道结果.

我希望我有道理.:)