0

0

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

青灯夜游

青灯夜游

发布时间:2021-07-06 11:30:18

|

3030人浏览过

|

来源于掘金社区

转载

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

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

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

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

异步编程案例一

function interview(callback) {
  setTimeout(() => {
    callback("success");
  }, 1000);
}

interview(function (res) {
  if (res === "success") {
    console.log("============我笑了");
  }
});

回调函数格式规范

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

为什么第一个参数是 error

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 是两个不同的事件循环!

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

Warp
Warp

新一代的终端工具(内置AI命令搜索)

下载
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 轮面试,

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

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

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

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

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

57

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

57

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

237

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

393

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

17

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

103

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

73

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

81

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

70

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Node.js 教程
Node.js 教程

共57课时 | 9.4万人学习

【web前端】Node.js快速入门
【web前端】Node.js快速入门

共16课时 | 2万人学习

Node.js-前端工程化必学
Node.js-前端工程化必学

共19课时 | 3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号