1、概念
Promise 表示一个异步操作的最终结果。
可以将Promise理解为一个状态机,它存在下面三种状态,并在某一时刻只能有一种状态:
Pending : 表示还在执行
Fulfilled(或resolved):执行成功
Rejected:执行失败。
一个Promise是对一个操作(通常是一个异步操作)的封装,异步操作有等待完成、成功、失败三种可能结果,对应了Promise三种状态。
例子:读取文件
let fs = require('fs');
let readFile_promise = (path) => {
return new Promise((resolve,reject) => {
fs.readFile(path,"UTF-8",(err,data) => {
if(data){
resolve(data);
}else{
reject(err)
}
})
})
}
//使用then方法接受数据
readFile_promise("./11.html").then((data) => {
console.log("succ:",data);
},(err) => {
console.log("err:",err);
})
//使用catch() 捕捉错误,效果和上面一样!
readFile_promise("./11.html").then((data) => {
console.log("succ:",data);
}).catch((err) => {
console.log("文件读取错误!",err);
})
then的用法:
第一个then方法中,再次调用了read_ promise,其返回的新的Promise覆盖了默认返回的Promise,我们因此可以在下一个then方法中获取另一个异步操作的执行结果。
let fs = require('fs');
let readFile_promise = (path) => {
return new Promise((resolve,reject) => {
fs.readFile(path,"UTF-8",(err,data) => {
if(data){
resolve(data);
}else{
reject(err)
}
})
})
}
//使用then方法接受数据
readFile_promise("./1.html").then((data) => {
console.log("succ:",data);
return readFile_promise("./a1.html"); //发起第二次读取
},(err) => {
console.log("第一次读取err:",err);
}).then((data) => {
console.log("data:",data);
},(err) => {
console.log("第二次读取err: ",err);
})
虽然通过then获取promise的结果,Promise从被创建的那一刻起就开始执行,then方法只提供了访问Promise状态的接口,与Promise无关。
二、Promise的常用接口
2.1 Promise.resolve 用来将一个非Promise对象转化为Promise对象,
注意:resolve方法不能转换异步方法。
let fs = require('fs');
let readFile_promise = (path) => {
return path;
}
Promise.resolve(readFile_promise("hello,world")).then((data) => {
console.log("data: ",data); //data: hello,world
})
//注意: Promise.reslove() 不能包裹一个异步函数
//或许读者想着可以使用resolve来转换一个异步方法,例如readFile之类的,很遗憾resolve方法做不到这一点,下面代码是无法执行的:
let fs = require('fs');
let readFile_promise = (path) => {
fs.readFile(path,"UTF-8",(err,data) => {
if(data){
return data;
}else{
return err;
}
})
}
Promise.resolve(readFile_promise("./1.html")).then((data) => {
console.log("data");
})
2.2 promise.reject()
返回一个promise对象,promise状态为reject,方法参数会将参数作为错误信息传递给then方法。
let readFile_promise = (param) => {
return param;
}
Promise.reject(readFile_promise("hello,world")).then((data) => {
console.log("data: ",data); //data: hello,world
})
2.3 Promise.all
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。
let fs = require('fs');
let readFile_promise = (path, time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
fs.readFile(path, "UTF-8", (err, data) => {
if (data) {
resolve(data);
} else {
reject(err)
}
})
}, time)
})
}
let p1 = readFile_promise("./1.html",3000);
let p2 = readFile_promise("./a.html",1000)
//使用then方法接受数据,所有resolve,才会resolve;有一个reject,就reject
Promise.all([p1, p2]).then((data) => {
console.log("succ:", data);
}, (err) => {
console.log("err:", err);
})
//注意的是,
//Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,
//即p1的结果在前,即便p1的结果获取的比p2要晚。
需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。
2.4 promise.race
race返回的Promise的状态由数组中率先执行完毕的Promise的状态决定
Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let fs = require('fs');
let readFile_promise = (path, time) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
fs.readFile(path, "UTF-8", (err, data) => {
if (data) {
resolve(data);
} else {
reject(err)
}
})
}, time)
})
}
let p1 = readFile_promise("./1.html",3000);
let p2 = readFile_promise("./a.html",1000)
//谁先执行完成,返回谁,无论对错
Promise.race([p1, p2]).then((data) => {
console.log("succ:", data);
}, (err) => {
console.log("err:", err);
})
第三方库:bluebird
来源:CSDN
作者:DriveMyLife
链接:https://blog.csdn.net/blackcat88/article/details/104569717