IO即为输入(input)和输出(output) 阻塞与非阻塞的区别在于输入后,输入方能不能去做其他的事情,如果不能则为阻塞,反正则为非阻塞。 以点菜为例,如果在食堂点菜,点菜阿姨需要把饭打好后,才能处理下一个同学的点菜。而在餐厅,服务员下单后,将单传给厨房,自己则可以继续为其他顾客下单。 在这个例子中,把订单传给厨房作为输入,点菜阿姨因为自己既是下单也是打饭的,下单后需要处理完当前订单才能让下一个同学下单,因此是阻塞的。而在餐厅,服务员下单后传给厨房,剩下的事就不是自己的职责范围了,可以给其他顾客服务,因此是非阻塞的。
调用interview方法的时候传递一个回调方法,interview执行结束的时候再调用这个回调方法,至于回调方法的参数第一个参数是err,第二个参数是返回结果都是约定俗成的
按下面这样是捕获不到错误的,因为node的事件循环机制,setTimeout会开启一个事件,会是一个全新的调用栈, node会循环判断这个事件是否已结束(是否一直循环暂时还不清楚),抛出错误后系统会崩溃,不会被捕获到,如果把setTimeout去掉则可以捕获到
try { interview(function (err, res) { if (err) { return console.log('cry') } console.log('smile') console.log(res) // success }) } catch(e) { console.log('报错了') // 这样是抓取不到错误的 } function interview(callback) { setTimeout(() => { num = Math.random() console.log(num) if (num > 0.4) { callback(null, 'success') } else { throw new Error('fail') } }, 500) }这种回调写法虽然简单,但是会带来下面这种情况,多次嵌套会出现回调地狱,代码难以阅读
interview(function(err, res) { if (err) { return console.log('cry') } interview(function(err, res) { if (err) { return console.log('cry') } interview(function(err, res) { if (err) { return console.log('cry') } console.log('interview success, smile') }) }) }) function interview(callback) { setTimeout(() => { num = Math.random() console.log(num) if (num > 0.4) { callback(null, 'success') } else { callback(new Error('fail')) } }, 500) }在promise还没有执行结果的时候是pending状态,执行成功后是resolved状态,执行失败是rejected状态,resovle和reject都只能接收一个参数
(function() { var promise = new Promise(function(resolve, reject) { setTimeout(() => { resolve(3); }, 300) }).then(function(res) { console.log(res) // 3 }).catch(function(err) { console.log(err) }) console.log(promise) // 打印状态,在浏览器Console中调试能看到状态的变化 })()
在浏览器中调试,查看promise的状态
await会等待后面的promise执行结束,从而达到同步的方式写异步
await后面跟着的就是promise
(async function() { try { await interview(1) await interview(2) await interview(3) } catch(err) { return console.log('第' + err.round + '轮面试失败了') } console.log('面试成功') })() function interview(round) { return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() > 0.4) { resolve('success') } else { var error = new Error('fail') error.round = round reject(error) } }, 100) }) }