【JavaScript】怎么使用回调函数解决异步问题

获取返回值

我们都知道同步API可以从返回值中拿到API执行的结果, 但是异步API却是不可以的

 // 同步
  function sum (n1, n2) { 
      return n1 + n2;
  } 
  const result = sum (10, 20);//30
// 异步
  function getMsg () { 
      setTimeout(function () { 
          return { msg: 'Hello Node.js' }
      }, 2000);
  }
  const msg = getMsg ();
  console.log(msg);//undefined

为什么会是undefined?
我们知道JavaScript的代码执行机制,会将异步代码放入任务队列中,而继续执行下面的同步代码,而造成undefined的原因正是异步函数还没有被触发,所以当调用getMsg ()函数时其中异步函数不阻塞线程,代码继续执行,getMsg ()函数默认return了一个undefined

所以这就造成了异步代码的不可控,我们根本不知道他什么时候执行,也就无法直接获取它的执行结果

那有办法解决么?
当然

回调函数获取异步API返回值

我们可以定义一个这样的函数:

function getData(callback) {
    callback(123);
}
getData(function(n) {
   console.log(n)//输出123
});

这就是回调函数

通过在函数形参中拿到的回调函数引用地址,可以调用回调函数并传递参数给回调函数的形参,这样回调函数就可以获得被调用函数中的信息

所以我们刚刚的代码可以写成这样

function getMsg (callback) {
	setTimeout(function () {
		callback({
			msg: 'hello node.js'
		})
	}, 2000)
}

getMsg(function (data) {
	console.log(data);
});

异步代码执行顺序

异步代码除了返回值还有一个执行顺序问题

console.log('代码开始执行');
setTimeout(() => {
    console.log('2秒后执行的代码');
}, 2000); 
setTimeout(() => {
    console.log('"0秒"后执行的代码');
}, 0);
console.log('代码结束执行');

上面的代码输出结果是什么呢?

我们知道JavaScript的代码执行机制,来分析一下:
很明显在执行栈中遇到异步代码,就会将其放到异步代码执行区,这时两个定时器都被放到异步代码执行区中了,然后在异步代码执行区中先触发的异步代码会先一步被放入任务队列中,等待调用

显然输出结果是先输出“0秒"后执行的代码”,然后再输出’2秒后执行的代码’

这样不可控制的输出顺序显然不是我们期望的,那么该如何解决呢?

回调函数控制异步代码执行顺序
function getData(callback) {
    setTimeout(() => {
        callback(123);
    }, 0);
}

console.log('代码开始执行');
getData(function(n) {
    console.log('callback函数被调用了')
    console.log(n)
    console.log('callback函数结束了')
});
console.log('代码结束执行');
//代码开始执行
//代码结束执行
//callback函数被调用了
//123
//callback函数结束了

我们看到在回调函数中代码是依次进行的

回调函数的作用就是,将异步代码写在一个块级作用域中,当其中的异步函数执行后,才会调用这个回调函数,这时异步函数已经执行完成,所以在回调函数中代码就可以如同步代码一样依次执行

所以问题就解决了,只需要在回调函数中调用其他的异步API就可以保证异步代码的顺序执行

function getData(callback) {
    setTimeout(function() {
        console.log('2s')
        setTimeout(function() {
            console.log('0s')
            callback(123);
        }, 0)
    }, 2000)


}

console.log('代码开始执行');
getData(function(n) {
    console.log(n)
});
console.log('代码结束执行');
//代码开始执行
//代码结束执行
//2s
//0s
//123
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
JavaScript中,回调函数是一种常见的编程模式,用于处理异步操作和事件处理回调函数是作为参数传递给其他函数,并在特定事件发生或异步操作完成时被调用。 以下是使用回调函数的示例: ```javascript function fetchData(callback) { // 模拟异步操作 setTimeout(function() { var data = "这是异步操作返回的数据"; callback(data); // 调用回调函数并传递数据 }, 1000); } function process(data) { console.log("处理数据:" + data);} fetchData(process); ``` 在上述示例中,`fetchData`函数模拟了一个异步操作,通过`setTimeout`延迟1秒钟后返回数据。在`fetchData`函数内部,我们调用了传递给它的回调函数,并将数据作为参数传递给回调函数。 `process`函数是一个回调函数,在数据返回后被调用,并对数据进行处理。在这个例子中,我们将返回的数据打印到控制台上。 回调函数还可以用于处理事件: ```javascript var button = document.getElementById("myButton"); function handleClick() { console.log("按钮被点击"); } button.addEventListener("click", handleClick); ``` 在上述示例中,我们给id为"myButton"的按钮添加了一个点击事件的监听器。当按钮被点击时,回调函数`handleClick`会被调用。 回调函数是一种强大的工具,可以使代码更具灵活性和可扩展性。通过将函数作为参数传递,我们可以在特定事件发生或异步操作完成后执行特定的逻辑。这种模式在处理异步请求、事件处理、定时器等方面非常常见和有用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

列队猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值