Promise 真的取代 callback 了吗
Promise 虽然改变了 JS 工程师对于异步操作的写法,但是却改变不了 JS 单线程、异步的执行模式。
本节概述
- JS 异步的本质
- Promise 只是表面的写法上的改变
- Promise 中不能缺少 callback
- 接下来...
JS 异步的本质
从最初的 ES3、4 到 ES5 再到现在的 ES6 和即将到来的 ES7,语法标准上更新很多,但是 JS 这种单线程、异步的本质是没有改变的。nodejs 中读取文件的代码一直都可以这样写
fs.readFile('some.json', (err, data) => {
})
既然异步这个本质不能改变,伴随异步在一起的永远都会有callback
,因为没有callback
就无法实现异步。因此callback
永远存在。
Promise 只是表面的写法上的改变
JS 工程师不会讨厌 JS 异步的本质,但是很讨厌 JS 异步操作中callback
的书写方式,特别是遇到万恶的callback-hell
(嵌套callback
)时。
计算机的抽象思维和人的具象思维是完全不一样的,人永远喜欢看起来更加符合逻辑、更加易于阅读的程序,因此现在特别强调代码可读性。而Promise
就是一种代码可读性的变化。大家感受一下这两种不同(这其中还包括异常处理,加上异常处理会更加复杂)
第一种,传统的callback
方式
fs.readFile('some1.json', (err, data) => {
fs.readFile('some2.json', (err, data) => {
fs.readFile('some3.json', (err, data) => {
fs.readFile('some4.json', (err, data) => {
})
})
})
})
第二种,Promise
方式
readFilePromise('some1.json').then(data => {
return readFilePromise('some2.json')
}).then(data => {
return readFilePromise('some3.json')
}).then(data => {
return readFilePromise('some4.json')
})
这两种方式对于代码可读性的对比,非常明显。但是最后再次强调,Promise
只是对于异步操作代码可读性的一种变化,它并没有改变 JS 异步执行的本质,也没有改变 JS 中存在callback
的现象。
Promise 中不能缺少 callback
上文已经基本给出了上一节提问的答案,但是这里还需要再加一个补充:Promise
不仅仅是没有取代callback
或者弃而不用,反而Promise
中要使用到callback
。因为,JS 异步执行的本质,必须有callback
存在,否则无法实现。
再次粘贴处之前章节的封装好的一个Promise
函数(进行了一点点简化)
const readFilePromise = function (fileName) {
return new Promise((resolve, reject) => {
fs.readFile(fileName, (err, data) => {
resolve(data.toString())
})
})
}
上面的代码中,promise
对象的状态要从pending
变化为fulfilled
,就需要去执行resolve()
函数。那么是从哪里执行的 ———— 还得从callback
中执行resolve
函数 ———— 这就是Promise
也需要callback
的最直接体现。
码农进阶题库 - 每天一道面试题 or Js小知识@Js中文网
每天弄懂一道面试题(Javascript小知识)来鞭策自己学习思考,每天进步一点,帮助你提高你的代码编写质量
接下来...
一块技术“火”的程度和第三方开源软件的数量、质量以及使用情况有很大的正比关系。例如为了简化 DOM 操作,jquery 风靡全世界。Promise 用的比较多,第三方库当然就必不可少,它们极大程度的简化了 Promise 的代码。
接下来我们一起看看Q.js
这个库的使用,学会了它,将极大程度提高你写 Promise 的效率。
看完两件小事
如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:
- 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
- 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程