深入浅析Node.js异步编程中的callback(回调)


本文摘自PHP中文网,作者青灯夜游,侵删。

非阻塞 I/O 的运行结果是需要回调函数来接收的,下面本篇文章给大家详细介绍一下Node.js异步编程中的callback(回调)。

【推荐学习:《nodejs 教程》】

非阻塞 I/O 的运行结果是需要回调函数来接收的,这种通过回调函数的方式就是异步编程!

异步编程案例一

1

2

3

4

5

6

7

8

9

10

11

function interview(callback) {

  setTimeout(() => {

    callback("success");

  }, 1000);

}

 

interview(function (res) {

  if (res === "success") {

    console.log("============我笑了");

  }

});

回调函数格式规范

  • error-first callbak
  • Node-style callback
  • 第一个参数是 error,后面的参数才是结果

为什么第一个参数是 error

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

function interview(callback) {

  setTimeout(() => {

    if (Math.random() < 0.3) {

      callback("success");

    }

    throw new Error("fail");

  }, 1000);

}

 

try {

  interview(function (res) {

    if (res === "success") {

      console.log("============我笑了");

    }

  });

} catch (error) {

  console.log("fail", error);

}

1.png

上面的代码中,try catch并不能捕获 throw new Error('fail') 抛出的错误!,而是抛出到了 JS 全局! 在 Node.js 中,全局错误时非常严重的事情,会造成程序的崩溃!

为什么没 try catch 无法捕获 setTimeout 里面的 throw 呢? 这就跟调用栈事件循环有关系了!

每一个事件循环都是一个全新的调用栈! setTimeout 与 interview 是两个不同的事件循环!

但是可以通过在回调函数中的参数抛出错误的方式来解决这个问题

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

function interview(callback) {

  setTimeout(() => {

    if (Math.random() < 0.3) {

      callback(null, "success");

    } else {

      callback(new Error("fail"));

    }

  }, 1000);

}

 

interview(function (error) {

  if (error) {

    return console.log("============我哭了");

  }

  console.log("============我笑了");

});

上面的代码中,可以根据参数的类型来判断是否出错! 但是 Node.js 中有很对回调函数, 我们不可能在每一个函数中都去判断参数类型是是否出错!

Node.js 规定第一个参数就是 erro,第二个参数就是结果!如果第一个参数不为空,则说明异步调用出错了!

异步流程控制的问题

回调地狱

多个异步任务串行的情况, 下面我们模拟一下 N 轮面试,

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

function interview(callback) {

  setTimeout(() => {

    if (Math.random() < 0.6) {

      callback(null, "success");

    } else {

      callback(new Error("fail"));

    }

  }, 1000);

}

 

interview(function (error) {

  if (error) {

    return console.log("======第一轮面试======我哭了");

  }

 

  interview(function (error) {

    if (error) {

      return console.log("====第二轮面试========我哭了");

    }

 

    interview(function (error) {

      if (error) {

        return console.log("====第三轮面试========我哭了");

      }

 

      console.log("三轮面试都成功了!啊哈哈哈!");

    });

  });

});

可以看到上面的异步流程做了三层嵌套,这还只是代码就比较简单的情况! 那么在实际应用中,每一个嵌套函数都可能非常复杂,这就造成难以开发和维护,看着让人生气,这就是所谓的** 回调地狱**

a

多个个异步任务并发的情况

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

function interviewCompay() {

  let count = 0;

  interview(function (error) {

    if (error) {

      return console.log("====第一家公司面试========我哭了");

    }

    count++;

  });

  interview(function (error) {

    if (error) {

      return console.log("====第二家公司面试========我哭了");

    }

    count++;

    if (count === 2) {

      return console.log("两家公司面试都成功了!我笑了");

    }

  });

}

interviewCompay();

在每一个异步任务里面都需要加入同一个变量才能捕获 多个异步任务的结果

解决异步流程的控制问题

  • promise
  • async await

更多编程相关知识,请访问:编程视频!!

以上就是深入浅析Node.js异步编程中的callback(回调)的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

浅谈使用node.js搭建一个简单的 http 服务器

微信支付成功,回调没有进来?

浅谈 node.js 中间件的工作原理

深入了解node.js 中的多线程和多进程

express中间件body-parser的实现方法

node.js真的单线程吗?进程间如何通信?

如何将 javascript 回调转换为 promise?方法介绍

node.js中怎么进行调试?

nodejs如何实现简单的get请求

为什么node.js要引入buffer?浅析缓冲区buffer

更多相关阅读请进入《node.js》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...