为何须要promise
- 回调地狱 若是多个异步请求 有连带关系 回调嵌套
- 多个异步实现并发的话,会出现没法同步异步的返回结果
- 错误处理不方便
什么是promise(承诺)
- promise 有三个状态 (成功态 Resolved 失败态 Rejected 等待态 Pending)
- 默认状况下 状态转换(状态不可逆)
- pending -> resolved
- pending -> rejected
- resolved 不能和rejected相互转换
- 用法:promise在ie下是不兼容的(能够使用webpack的polyfill等方式解决)
// new Promise的时候 须要传递一个executor执行器,执行器函数会默认被内部所执行
new Promise(function(resolve,reject){
// 若是在这里调用了resolve 就会变成成功态
console.log('hello') // 第一个执行
})
console.log('hello1') // 第二个执行
复制代码
let p = new Promise(function(resolve.reject){
resolve();
})
// 每一个promise(实例)都有一个then方法
// then方法是一个异步方法,默认不会再当前的上下文中执行(微任务)且比setTimeout先执行
p.then(function(){
console.log('成功')
},function(){
console.log('失败')
})
复制代码
// 面试题
setTimeout(function(){
console.log(1)
},0)
new Promise(function(resolve){
console.log(2)
for(var i = 0;i<10;i++){
i==9 && resolve()
}
console.log(3)
}).then(function(){
console.log(4)
})
console.log(5)
// 2 3 5 4 1
复制代码
promise解决异步的基本使用
- promise 每次调用then后,分下面几种状况
- 若是返回的是promise 用promise的成功或者失败 执行下一个then
- 若是返回的是一个普通值(包括不写return,默认return undefined)会走外层下一个then的成功
- 若是执行的时候,抛出异常就会走到下一个then中的失败
- then中能够不传递参数,若是不传递 会透到下一个then中
- catch用来捕获错误的,至关于then的第一个参数传递null catch以后仍然能够继续then
let fs = require('fs')
function read(file){
return new Promise(function(resolve,reject){
fs.readFile(file,'utf8',function(err,data){
if(err) reject(err)
resolve(data)
})
})
}
// promise的链式调用
read('./name.txt').then(function(data){
// then方法成功后 返回的是一个新的promise 这个返回的promise会被执行,若是返回的promise是成功的,会把这个结果传递到外层的下一个then中
// return read(data) 返回下一个then成功
// throw new Error('出错了') 返回下一个then失败
return data // 返回下一个then成功
},function(err){
console.log(err)
}).then(function(data){
console.log('age',data)
}).then().catch(function(err){
console.log('error',err)
}).then(function(data){
console.log(data)
})
复制代码
// 面试题
new Promise(function(resolve,reject){
resolve(1)
})
.then(function(data){
console.log(data)
return 2;
})
.catch(function(err){
return 3;
})
.then(function(res){
console.log(res)
})
// 1 2
复制代码
Promise.all(promise提供了一个 并发的方法 Promise.all 返回的结果是一个promise,只有传递的promise数组所有成功才会返回成功态)
Promise.all([read('./name.txt'),read('./age.txt')]).then(function(data){
console.log(data)
}).catch(function(err){
console.log(err)
})
复制代码
Promise.race(只要有一个返回成功 就返回成功态)
Promise.race([read('./name.txt'),read('./age.txt')]).then(function(data){
console.log(data)
}).catch(function(err){
console.log(err)
})
复制代码