1

是在是不想拿别人文章里面的那种,写了n个参数,n堆执行语句的例子来提问。
我自己写了三个简单的例子,例子里面包含了我对回调函数的理解和疑问。我看阮老师的文章也是,开门就说callback是异步编程的一种解决方案。可是我依然没弄明白之间有什么关系。

//例1
var callback = function(num3) {
    console.log('执行回调函数:' + num3)
  }

function fn(num1, num2, cb) {
  var Total = num1 + num2;
  cb(Total);
  console.log('求和Total:' + Total)
}

fn(2, 2, callback)

执行结果:
//执行回调函数:4
//求和Total:4
//例2
function f2() {
    console.log('f2 finished') 
}

function f1(cb) {
    setTimeout(cb,0)        //用setTimeout()模拟耗时操作
    console.log('f1 finished')
}

f1(f2);

执行结果:
//省略
//例3
function f2() {
    setTimeout(()=>{
     console.log('f2 finished') 
    },0)    
}

function f1(cb) {
    cb(); 
    console.log('f1 finished')
}

f1(f2);

执行结果:
//省略
张呵呵 306
2018-12-21 提问
6 个回答
0

已采纳

我也来尝试回答一下。

看了楼上那么多答案以及你的追问,我感觉你迷惑的地方在于你不了解“异步函数”和普通的“同步函数”之间到底有什么区别。

其实它们之间的主要区别在于“事件循环队列”,如果你是第一次听说这个词,可能会被吓到那么一下下,如果你并不是第一次听说,那么你可能是没有真正理解它以及它和异步函数之间的关系。

其实很简单,事件循环队列只是一个“待办事项清单”,注意是“待办”,而不是“立即办”。加入待办清单的是异步,没有加入待办清单的是同步。本质区别正在于此。

事件循环队列不直接向JS代码开放,所以我们不能直接操作它,只能通过间接的方法,主要有以下几种:

  1. 内置的定时器函数(setTimeout/clearTimeout、setInterval/clearInterval)
  2. 异步模式的Ajax请求
  3. 新创建的Promise对象
  4. async函数(本质还是Promise)

以上4种都是异步的,除此之外的代码都是同步的(除非js以后加入了新的异步方式)。

比如说定时器,它会将一个函数放到事件队列中去,等到未来的某个时刻执行。即使传入的时间为0也是一样,所以下面的代码会先打印2再打印1:

setTimeout(() => console.log(1), 0);
console.log(2);

所以总结一下:

  1. 异步函数和同步函数之间的区别关键在于事件循环队列
  2. 并不是回调函数的使用使得一个函数成为异步函数,同步函数同样可以使用回调
  3. js只有固定的几种方法可以创建异步函数,除此之外都是同步的
1

首先 回调函数 其实就是一个普通的函数,和异步没什么关系;

其次 为什么回调什么老是和异步混一起出现, 主要是因为大家常用回调函数来接收异步操作的反馈(包括成功和出错);

打个比方:
体育老师(主线程)给了学生一个电话(回函数)让学生去跑10圈(异步操作),和学生约定,跑完了(完成)再打他电话,跑的时候如果受伤了(出错)就直接打医务室的电话, 然后学生开始跑圈,老师吃干别的事去了.

如果异步操作不需要反馈, 就不需要回调函数;
//这是一个典型的回调函数, 一般约定 ,第一个参数是错误信息, 后面的参数就结果.
var callBack = function(err,val){
    if(err) return console.log("异步函数出错了!");
    console.log("操作成功!");
    if(val) console.log("结果是:",val);
}

//定义一个异步函数, 回调可以用来接收结果,也可以接收错误.
function syncFn(a,b,cb){
    setTimeout(function(){
        try{
            var v = a + b; 
            cb(null,v);
        }catch(e){
            cb(e)
        }
    },100)
}
0

没明白这三个例子想表达什么,首先第一个例子跟异步没有关系,就是把函数作为参数传递而已,跟调用栈有关;第二个例子 setTimeout 是一个异步方法,会把传入的函数作为回调函数放进队列里;第三个例子同理。

0

没有必然关系吧,只不过回调是处理异步的常用方式

0

setTime不管是0还是什么都会放入另一个队列,这是浏览器的行为。异步不异步js执行机制有规定的,浏览器内部就自己这样搞得

回调就是为了保证能够在某个条件达成的时候再去执行下一步

0

楼上说得很对。回调函数是异步API反馈主线程的一种方式,不是用来实现异步的。异步的典型实现方式是协程。

撰写答案

推广链接