【推荐学习:《nodejs 教程》】
非阻塞 I/O 的运行结果是需要回调函数来接收的,这种通过回调函数的方式就是异步编程!
异步编程案例一
function interview(callback) { setTimeout(() => { callback(success); }, 1000); } interview(function (res) { if (res === success) { console.log(============我笑了); } });
回调函数格式规范
为什么第一个参数是 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); }
上面的代码中,try catch
并不能捕获 throw new Error('fail')
抛出的错误!,而是抛出到了 JS 全局! 在 Node.js 中,全局错误时非常严重的事情,会造成程序的崩溃!
为什么没 try catch
无法捕获 setTimeout 里面的 throw
呢? 这就跟调用栈 和 事件循环有关系了!
每一个事件循环都是一个全新的调用栈! setTimeout
与 interview 是两个不同的事件循环!
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
更多编程相关知识,请访问:编程视频!!