Promise
解决回调地狱
1.封装fs模块
const { rejects } = require("assert");
const fs = require("fs");
const { resolve } = require("path");
function get(path){
return new Promise((resolve,rejects)=>{
fs.readFile(path,'utf-8',(err,data)=>{
if (err){
rejects(err);
}
resolve(data);
})
})
}
get("./content.txt").then(value=>{
console.log(value.toString());
},reason=>{
console.log(reason);
}
)
util.promisify
const util = require("util");
const fs =require("fs");
let get = util.promisify(fs.readFile);
get('./content.txt').then(
value=>{
console.log(value.toString());
}
)
2.封装ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function send(url){
return new Promise((resolve,rejects)=>{
const xhr = new XMLHttpRequest();
xhr.open("GET",url);
xhr.send();
xhr.addEventListener("readystatechange",()=>{
if (xhr.readyState===4){
if (xhr.status >=200 && xhr.status <300){
resolve(xhr.response);
}else{
rejects(xhr.status);
}
}
})
})
}
send("http://localhost:8030/serve").then(value=>{
console.log(value);
},reason=>{
console.log(reason);
})
</script>
</body>
</html>
3.Promise 有三种状态:
pending (等待态)
fulfiled (成功态)
rejected (失败态)
Promise 状态的转变是不可逆且只能发生一次
也就是说,一个 Promise 不能从 fulfiled 状态变回 pending 状态,也不能从 rejected 状态变为
pending 或者 fulfiled 状态
一旦 Promise 从 pending 状态变为 fulfiled 或 rejected ,它就永远不会再改变
4.Promise方法
//executor执行器,立即执行
let p = new Promise((resolve,reject)=>{
console.log(111);
})
console.log(222);
1.Promise.resolve方法
如果传入的参数为非类型的对象,则返回的结果为成功的Promise对象
如果传入的参数为对象。则参数的结果决定了resolve的结果
let p1 =Promise.resolve(5222);
console.log(p1);
2.Promise.reject方法
返回一个失败的Promise对象
let p2 = Promise.reject("sdalds");
console.log(p2);
3.Promise.all方法
(promises) => {}
包含n个promise的数组
说明:返回一个新的promise,只有所有的promise都成功才成功
const pro1 = new Promise((resolve,reject)=>{
resolve("OK");
})
const pro2 = new Promise((resolve,reject)=>{
resolve("OK");
})
const pro3 = new Promise((resolve,reject)=>{
resolve("OK");
})
let res = Promise.all([pro1,pro2,pro3]);
console.log(res);
4.Promise.race方法
返回一个新的promise,返回的是第一个完成的promise
Promise关键问题
改变对象状态
let p = new Promise((resolve,reject)=>{
//pending=>fulfilled
resolve("ok");
//pending=>rejected
reject("error")
//pending=>rejected
throw 'error';
})
console.log(p);
多次回调,状态改变会调用
let p = new Promise((resolve,reject)=>{
resolve("ok");
})
p.then(value=>{
console.log(value);
})
p.then(value=>{
alert("1")
})
then
then的返回结果是由指定的回调函数的执行结果决定的
let p = new Promise((resolve,reject)=>{
resolve("ok");
})
p.then(value =>{
console.log(1);
//1
throw "错误";
//2
return "sdad";
//3new 的promise对象的返回结果是then返回promise对象的结果
return new Promise((resolve,reject)=>{resolve("ok");})
},reson=>{
console.log(2);
})
promise异常穿透
在后面使用catch
let p = new Promise((resolve,reject)=>{
resolve("ok");
})
p.then(value =>{
console.log(1);
},reson=>{
console.log(2);
}).then(value=>{
console.log(value);
}).then(value=>{
console.log(value);
}).catch(reason=>{
console.log(reason);
})
中断promise链
p.then(value =>{
console.log(1);
//唯一方法
return new Promise(()=>{});
},reson=>{
console.log(2);
}).then(value=>{
console.log(value);
}).then(value=>{
console.log(value);
}).catch(reason=>{
console.log(reason);
})
5.自定义封装
/* 封装为一个类 */
class promise{
constructor(executor){
//1.修改属性
this.PromiseState = 'pending';
//2.设置结果
this.PromiseResult = 'null';
this.callbacks=[];
/* 保存实例对象值 */
const self = this;
function resolve(data){
if (self.PromiseState !== 'pending') return;
self.PromiseState = 'fulfilled';
self.PromiseResult = data;
/* if (self.callback.onReadySolve){
self.callback.onReadySolve(data);
} */
setTimeout(()=>{
self.callbacks.forEach((item)=>{
item.onReadySolve(data);
});
});
}
//reject
function reject(data){
if (self.PromiseState !== 'pending') return;
self.PromiseState = 'rejected';
self.PromiseResult = data;
/* if (self.callback.OnRejected){
self.callback.OnRejected(data);
} */
setTimeout(()=>{
self.callbacks.forEach((item)=>{
item.OnRejected(data);
});
});
}
//同步调用
try {
executor(resolve,reject);
} catch (e) {
reject(e);
}
}
then(onReadySolve,OnRejected){
//调用回调函数
const self = this;
if (typeof OnRejected !== 'function'){
OnRejected = reason=>{
throw reason;
}
}
if (typeof onReadySolve !== 'function'){
onReadySolve = value => value;
}
return new promise((resolve,reject)=>{
/* 保存this */
const self = this;
function callback(type){
try {
let result1 = type(self.PromiseResult);
if (result1 instanceof promise){
result1.then(v=>{
resolve(v);
},r=>{
reject(r)
})
}else{
resolve(result1);
}
} catch (e) {
reject(e);
}
}
if (this.PromiseState === 'fulfilled'){
setTimeout(()=>{
callback(onReadySolve);
})
}
if (this.PromiseState === 'rejected'){
setTimeout(()=>{
callback(OnRejected);
})
}
if (this.PromiseState === 'pending'){
//保存回调
this.callbacks.push( {
onReadySolve:function(){
callback(onReadySolve);
},
OnRejected:function(){
callback(OnRejected);
}
})
}
});
}
catch = function(OnRejected){
return this.then(undefined,OnRejected);
};
static resolve = function(value){
return new promise((resolve,reject)=>{
if (value instanceof promise){
value.then(v=>{
resolve(v);
},r=>{
reject(r);
})
}else{
resolve(value);
}
});
}
all = function(promises){
return new promise((resolve,reject)=>{
let count=0;
let arr =[];
for (let i=0;i<promises.length;i++){
promises[i].then(v=>{
/* 每个都成功都 */
//resolve()
count++;
arr[i]=v;
if (count===promises.length){
/* 调用resolve修改状态 */
resolve(v)
}
},r=>{
reject(r);
})
}
});
}
static reject = function(reason){
return new promise((resolve,reject)=>{
reject(reason);
});
}
/* race方法 */
race = function(promises){
return new promise((resolve,reject)=>{
let count=0;
let arr =[];
for (let i=0;i<promises.length;i++){
promises[i].then(v=>{
resolve(v)
},r=>{
reject(r);
})
}
});
}
}
6.async
async function main(){
return new Promise((resolve,reject)=>{
//resolve("OK");
reject("ERROR");
})
throw "DZ";
}
let result = main();
console.log(result);
await
await必须写在async里,但是async里可以没有await
如果await的promise失败了,就会抛出异常,需要通过try catch捕获处理
let p = new Promise((resolve,reject)=>{
//resolve("OK");
reject("ERROR");
})
/* let res = await p;
console.log(res);
let res2 = await 20;
console.log(res2); */
try {
let res = await p;
} catch (e) {
console.log(e);
}
}
结合案例
const fs = require("fs");
const util = require("util")
const minereadfile = util.promisify(fs.readFile);
/* fs.readFile("../res/1.html","utf-8",(err,datastr1)=>{
if (err) throw err;
fs.readFile("../res/2.html","utf-8",(err,datastr2)=>{
if (err) throw err;
fs.readFile("../res/3.html","utf-8",(err,datastr3)=>{
if (err) throw err;
console.log(datastr1+" "+datastr2+" "+datastr3);
})
})
}) */
async function main(){
let datastr1 = await minereadfile("../res/1.html");
let datastr2 = await minereadfile("../res/1.html");
let datastr3 = await minereadfile("../res/1.html");
console.log(datastr1+" "+datastr2+" "+datastr3);
}
main();