关于回调函数的问题,请大佬们解答下,谢谢 20C

今天百度了一天回调函数的内容,知道了回调函数实际上是将整个函数以一个参数的形式传递给另一个参数,但是在用Jquery的ajax时一直搞不明白,我们执行完一个url后会返回数据data,然后success(data)会再进一步处理数据,success就是回调函数了,但完全搞不懂为什么这个回调函数是在主体函数执行完才结束的,难道说主体函数结束的最后一句语句就是调用这个回调函数吗?还是说js有自己的机制,检测到是回调函数就会用浏览器的异步形式去处理,再放到队列中等到主体函数执行完再放进栈中处理?求教大神帮忙解答一下,困惑了一天。

2个回答

如果你看了原生的ajax代码就会明白

function getData(url,success) {
    //步骤一:创建XMLHttpRequest对象
    var ajax = new XMLHttpRequest();
    //步骤二:设置请求的url,这里true是异步方式请求
    ajax.open('get',url,true);
    //步骤三:发送请求
    ajax.send();
    //步骤四:注册事件 onreadystatechange 当请求状态改变时触发
    ajax.onreadystatechange = function () {
        if (ajax.readyState==4 && ajax.status==200) {
            //步骤五 如果能够进到这个判断 说明数据取回来了
            success(ajax.responseText);//调用回调函数并传递数据
        }
    }
}

getData("xxxx.php",function (data) {
    console.log(data);
})

代码先是创建一个XMLHttpRequest对象,并用ajax.open('get',url,true);ajax.send()设置和发送请求。
但是这个请求是异步的,代码不会在这里等待这个请求完成,而是继续执行之后的代码。
那么怎么知道这个请求完成了呢?
这就要为XMLHttpRequest对象注册事件 onreadystatechange ,当请求状态改变时就会触发这个事件,
当ajax.readyState==4 && ajax.status==200时,就说明请求的数据完成了,这时就可以调用success()回调函数。

这其实与 window.onload 事件在页面加载完成时执行是一个意思。

其实就是 同步回调 异步回调。 假如一个png要加载10s,如果用同步回调,那么界面就要卡10s;
但是异步就可以在这10s里干别的事,等图片加载完在调用回调函数。
异步一般就涉及到多线程,题主可以看看java的多线程异步回调,我感觉比js更好理解。

 // 比较两个数是否相等

var a = 10;
var b = 10;

//同步回调
function equals1(a, b, callback) {
    var ret = a === b;
    callback(ret);
    console.log("equals1 => " + ret)
}

//(伪)异步回调
function equals2(a, b, callback) {
    var ret = a === b;
    setTimeout(function() {
        callback(ret)
    }, 1000); //模拟一个 1s 的耗时操作
    console.log("equals2 => " + ret)
}

var callback = function(ret) {
    console.log("callback => " + ret)
}

equals1(a, b, callback);
equals2(a, b, callback);

真正的异步回调

 class Test {
    private void start() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                callback("来自子线程异步回调");
            }
        }).start();
        callback("来自主线程同步回调");
    }

    private void callback(String str) {
        System.out.println(str);
    }

    public static void main(String[] args) {
        new Test().start();
        System.out.println("主线程");
    }
}
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问