Promise是什么?
Promise从含义上讲,它是一个异步操作的解决方案,从语法本质上讲,它就是一个构造函数,函数内部是要进行的异步操作,它由社区最早提出和实现,ES6将其写进了语言标准,统一了语法,原生提供了Promise。
下面给出一个Promise的使用场景:使用Promise对象,给定一个文件路径,去读取文件的内容
const fs = require('fs')
function getFileByPath(fpath) {
return new Promise(function(resolve, reject) {
fs.readFile(fpath, 'utf-8', (err, dataStr) => {
if (err) return reject(err)
resolve(dataStr)
})
})
return promise
}
//调用
getFileByPath('./files/2.txt').then(function(data) {
console.log(data + '--------')
}, function(err) {
console.log(err.message)
})
读取文件在js里面需要异步操作,因为js是单线程执行环境,如果这个操作不使用异步,程序就得等待读文件操作结束后,才能执行下一个任务,这样会增加页面的响应时间,从而带来较差的用户体验。
Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 方法和 reject 方法。在Promise对象创建的时候,resolve和reject两个方法作为形参传入Promise对象的函数中。
我们可以通过Promise对象.then()来指定promise对象的resolved状态rejected的状态。
如果异步操作成功,则用 resolve 方法将 Promise 对象的状态,从「未完成」变为「成功」(即从 pending 变为 resolved);
如果异步操作失败,则用 reject 方法将 Promise 对象的状态,从「未完成」变为「失败」(即从 pending 变为 rejected)。
上面代码中的resolve方法在调用时指的是:
function(data) {
console.log(data + '--------')
}
reject方法在调用中指的是:
function(err) {
console.log(err.message)
}
为什么要用Promise?
这时有人可能就会说,异步操作为什么要用Promise,用回调函数或者事件机制不也能够实现异步,那我们来看下面这个用回调函数实现的异步场景:
getFileByPath('./files/1.txt').then(function(data) {
console.log(data)
getFileByPath('./files/2.txt').then(function(data){
console.log(data);
getFileByPath('./files/3.txt').then(function(data){
console.log(data);
...
}
}
}
当更多的文件请求被回调时,代码结构上就会变得难以理解,称它为回调地狱。
这是我们可以用Promise来解决这个问题,并让我们的代码变得简洁易懂:
getFileByPath('./files/1.txt')
.then(function(data) {
console.log(data)
return getFileByPath('./files/2.txt') //通过return一个新的Promise对象
}
.then(function(data) {
console.log(data)
return getFileByPath('./files/3.txt')
})
.then(function(data) {
console.log(data)
})
//在上一个.then中,返回一个新的promise实例,可以继续用下一个.then来处理
这样写的优点在于回调函数变成了链式写法,程序的流程可以看得很清楚,理解起来也更加方便。
当然,这只是Promise的一个好处,还有其他的好处菜鸟飞还需要继续学习。
网友评论