Promise学习(二)
使用util中的promisify自动封装err,data类的回调转换为promise风格
//引入fs
const fs = require('fs');
//引入util
const util = require('util')
//将err,data类的的回调转换为promise风格
let mineReadFile = util.promisify(fs.readFile);
mineReadFile('./resource/content.txt').then(value=>{
console.log(value.toString());
})
封装Promise风格的AJAX
<script>
function senAJAX(url){
return new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest();
xhr.open("GET",url);
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status>=200&&xhr.status<300){
resolve(xhr.response)
}else{
reject(xhr.status)
}
}
}
});
}
senAJAX('https://api.apiopen.top/getJoke')
.then(value=>{
console.log(value);
},reason=>{
console.log(reason)
})
</script>
Promise的状态
实例对象中的属性【PromiseState】值为:
- pending(未决定的)
- resolved/fullfilled(成功)
- rejected(失败)
promise的状态只能改变一次且只能由未决定转换为成功或者为失败。
Promise对象的值
实例对象中的另一个属性【promiseResult】
保存异步任务对象成功或者失败的结果
- resolve
- reject
Promise的API
1.构造函数(同步调用的)
2.then方法(可以指定成功的回调和失败的回调)
3.catch方法(只能制定失败的回调)
p.catch(reason=>{
console.log(reason);
})
4.resolve
<script>
//该方法只属于Promise函数对象,并不属于实例对象
//可以传递一个参数
//如果为非promise类型的对象,那么就是一个成功的promise
//反之参数的结果决定结果
let p1 = Promise.resolve(111);
p1.then(value=>{
console.log(value);
},reason=>{
console.log(reason);
})
let p2 = Promise.resolve(new Promise((resolve,reject)=>{
reject("失败惹")
}))
console.log(p2)
p2.then(value=>{
console.log(value);
},reason=>{
console.log(reason);
})
</script>
5.reject
与resolve不同,他接收一个参数,一直都返回失败。
let p =Promise.reject("必定失败惹");
6.all
参数可以包含n个promise的数组,只有当所有的promise都成功的时候,才会成功,并返回一个所有promise返回成功所构成的数组。当失败的时候,返回失败的promise的结果。
let p1 =Promise.resolve('I');
let p2 =Promise.resolve('am');
let p3 =Promise.resolve('Success');
const result = Promise.all([p1,p2,p3]);
result.then(value=>{
console.log(value)
},reason=>{
console.log(reason)
})
7.race
参数可以包含n个promise的数组,状态和结果都由第一个完成的promise决定
改变Promise对象的状态
let p = new Promise((resolve,reject)=>{
//1
resolve('success');
//2
reject('error');
//3,状态是一个失败状态
throw 'err'
})
一个Promise制定多个成功/失败的回调函数时,都会调用
<script>
let p = Promise.resolve('hello')
p.then(value=>{
console.log(value)
})
p.then(value=>{
console.log(value+'2')
})
</script>
改变promise的状态和指定回调函数谁先谁后?
- 当promise的执行器里面为同步任务时,先改变状态,再指定回调。
- 当promise的执行器里面为异步任务时,先指定回调,再改变状态。
但无论如何,回调函数的执行,一定是在改变状态之后的。
then方法返回的新promise对象的结果状态由什么来决定?
是由then方法指定的回调函数执行结果决定
- 抛出异常(失败状态)
- 非Promise类型的对象(成功状态)
- Promise类型的对象(依据该promise对象的状态决定)
Promise如何串联多个操作任务
通过在promise的then方法中返回另一个promise对象
<script>
let p = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('ok');
},1000);
});
p.then(value=>{
return new Promise((resolve,reject)=>{
resolve("success");
});
}).then(value=>{
console.log(value)
})
</script>
Promise的异常穿透
当使用串联多个Promise时,设置失败的回调,只需要在最后一个promise对象中设定,只要在前面的任意位置失败,那么都会调用最后的失败回调。
中断Promise链
//中断Promise链,返回一个pending状态的Promise对象
return new Promise(()=>{})
async函数和await表达式
async函数
- 函数的返回值为promise对象。
- promise对象的结果由async函数执行的返回值决定。
<script>
async function main(){
return new Promise((resolve,reject)=>{
reject('err')
})
}
let result = main();
console.log(result)
</script>
await表达式
- await右侧的表达式一般为promise对象,但也可以是其他的值
- 如果表达式是promise对象,await返回的是promise成功的值
- 如果表达式是其他值,直接将此值作为await的返回值
注意
await必须写在async函数中,但async函数中可以没有await
如果await的promise失败了,就会抛出异常,需要通过try...catch捕获处理
await返回的是promise成功后的数据
await是用来免写回调函数的
<script>
async function main(){
let res = await new Promise((resolve,reject)=>{
resolve('ok')
})
console.log(res)
}
let result = main();
</script>