ES6中promise的使用
本文目录
- ES6中promise的使用
- 基础介绍
- 箭头函数
- function函数
- 状态
 
- 原型方法
- Promise.prototype.then()
- Promise.prototype.catch()
 
- 静态方法
- Promise.all()
- Promise.race()
- Promise.any()
 
- 链式回调
 
 
基础介绍
官网:https://promisesaplus.com/
window.Promise
 
 
箭头函数
let p1 = new Promise((resolved, rejected) => {
  console.log("p1 Promise");
})
console.log(p1);
function函数
let p2 = new Promise(function (resolve, reject) {
  console.log("p2 Promise");
});
console.log(p2);
new Promise函数是同步函数,是立即执行的
  
 
状态
promise共有三种状态:pending / fulfilled / rejected
状态转换
- pending -> fulfilled:成功状态
- pending -> rejected:失败状态
let p = new Promise((resolved, rejected) => {
  console.log("p Promise");
  // resolved()
  // rejected()
})
console.log(p);



- 竞争
    
原型方法
Promise.prototype.then()
-  then方法接收两个参数,一个是成功时的回调函数,一个是失败时的回调函数let p = new Promise(function (resolve, reject) { // 将状态修改为成功 resolve("BNTang"); // 将状态修改为失败 // reject("BNTang"); });指针函数 p.then( (val) => { console.log("val = " + val); }, (err) => { console.log("err = " + err); } )function函数 p.then( function(val){ console.log("val = " + val); }, function(err){ console.log("err = " + err); } )function函数2 function success(data) { console.log("成功", data); } function error(data) { console.log("失败", data); } promise.then(success, error);
-  Promise需要有返回值,在PromiseResult中可以查看
  
-  如果 new Promise中没有回调;则then里的函数不会执行let p = new Promise((res,rej)=>{ }) p.then(val=>{ console.log(11); // 11不输出 })  
-  then获取返回值,成功则进入第一个函数,失败进入第二个函数function f() { return "ghn" } let p = new Promise((resolved, rejected) => { // resolved(f()) rejected(f()) }) p.then( (val) => { console.log("val = " + val); }, (err) => { console.log("err = " + err); } ) console.log(p)   
-  then也会返回一个新的Promise对象,这个新Promise的状态取决于回调函数的执行情况,默认是undefinedlet p = new Promise((res, rej) => { res(11) }) let p1 = p.then( (val) => { console.log("val1= " + val); return { name: 'ghn' } }, (err) => { console.log("err1 = " + err); } ) p1.then(value => { console.log("p1-then = " + JSON.stringify(value)); }) console.log(p); console.log(p1);   
-  then中抛出异常或返回失败,第二个then的promise实例状态是根据p.then的返回值决定的let p = new Promise((res, rej) => { res(11) }) let p1 = p.then( (val) => { console.log("val1= " + val); // return { name: 'ghn' } return new Promise((resolved, rejected) => { rejected(2) }) // throw new Error("my error") }, (err) => { console.log("err1 = " + err); } ) p1.then((val) => { console.log("p1-then = " + JSON.stringify(val)); },(err) => { console.log("p1-then-err = " + JSON.stringify(err)); }) console.log(p); console.log(p1);   
Promise.prototype.catch()
-  基础使用 p.then( (data) => { console.log('resolved',data); },(err) => { console.log('rejected',err); } ); p.then((data) => { console.log('resolved',data); }).catch((err) => { console.log('rejected',err); });
-  使用 catch捕获异常let p = new Promise((res, rej) => { res(11) }) let p1 = p.then( (val) => { console.log("val1= " + val); // return { name: 'ghn' } // return new Promise((resolved, rejected) => { // rejected(2) // }) throw new Error("my error") }, (err) => { console.log("err1 = " + err); } ).catch(err => { console.log("catch = " + err.message); // 根据错误类型判断是否继续抛出 if (err instanceof Error) { // 如果错误是使用 new Error() 创建的,则不再继续传递 return; } // 如果错误是其他类型,如Promise的reject方法传递的值,则继续抛出 throw err; }) p1.then((val) => { console.log("p1-then = " + JSON.stringify(val)); },(err) => { console.log("p1-then-err = " + JSON.stringify(err)); }) console.log(p); console.log(p1);   
静态方法
Promise.all()
Promise.all() 方法是 && 的关系;Promise.any() 方法是 || 的关系; Promise.race()方法是 赛跑机制
var p = Promise.all([p1, p2, p3]);
- 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数
let p1 =new Promise(function(resolve,reject){
   resolve(1);
});
let p2 = new Promise(function(resolve,reject){
   resolve(2);
});
let p3 = new Promise(function(resolve,reject){
   resolve(3);
});
Promise.all([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});
 
 
- 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
let p1 =new Promise(function(resolve,reject){
   resolve(1);
});
let p2 = new Promise(function(resolve,reject){
   resolve(2);
});
let p3 = new Promise(function(resolve,reject){
   reject(3);
});
Promise.all([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});
 
 
- Promise.all()方法提供了并行执行异步操作的能力,在- all中所有异步操作结束后才执行回调
function p1() {
  var promise1 = new Promise(function (resolve, reject) {
    console.log("p1的第一条输出语句");
    resolve("p1完成");
  });
  return promise1;
}
function p2() {
  var promise2 = new Promise(function (resolve, reject) {
    console.log("p2的第一条输出语句");
    setTimeout(() => {
      console.log("p2的第二条输出语句");
      resolve("p2完成");
    }, 2000);
  });
  return promise2;
}
function p3() {
  var promise3 = new Promise(function (resolve, reject) {
    console.log("p3的第一条输出语句");
    resolve("p3完成");
  });
  return promise3;
}
Promise.all([p1(), p2(), p3()]).then(function (data) {
  console.log(data);
});
 
 
- Promise.all()获得的成功结果的数组里面的数据顺序和接收到的数组顺序是一致的,即- p1的结果在前,即便- p1的结果获取的比- p2要晚
// 在前端开发请求数据的过程中,会遇到发送多个请求并根据请求顺序获取和使用数据的场景
let wake = (time) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`${time / 1000}秒后醒来`)
    }, time)
  })
}
 
let p1 = wake(3000)
let p2 = wake(2000)
 
Promise.all([p1, p2]).then((result) => {
  console.log(result)       // [ '3秒后醒来', '2秒后醒来' ]
}).catch((error) => {
  console.log(error)
})
 
 
Promise.race()
- Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败
let p1 =new Promise(function(resolve,reject){
   resolve(1);
});
let p2 = new Promise(function(resolve,reject){
   resolve(2);
});
let p3 = new Promise(function(resolve,reject){
   resolve(3);
});
Promise.race([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});
 
 
- 使用场景:几个服务器的好几个接口都提供同样的服务,不知道哪个接口更快,可以使用Promise.race
let p1 = new Promise(function(resolve,reject){
  setTimeout(() => {
    resolve(1);
  }, 1000);
});
let p2 = new Promise(function(resolve,reject){
   reject(2);
});
let p3 = new Promise(function(resolve,reject){
   resolve(3);
});
Promise.race([p1, p2, p3]).then(function (results) {
   console.log('success:'+results);
}).catch(function(r){
   console.log("error");
   console.log(r);
});
 
 
Promise.any()
- 只要p1,p2状态有一个变为fulfilled,该实例的状态为fulfilled
const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});
 
const pSlow = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, "最终完成");
});
 
const pFast = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, "很快完成");
});
 
Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
},(err) => {
  console.log(err);
}).catch((aggregateError) => {
   console.log("error");
   console.log(aggregateError);
});
// expected output: "很快完成"
 
 
- 如果所有的 Promises都失败,该实例的状态将失败(rejected),结果值是包含所有失败状态的AggregateError的实例的结果集
const pErr = new Promise((resolve, reject) => {
  reject("总是失败");
});
 
const pSlow = new Promise((resolve, reject) => {
  setTimeout(reject, 500, "最终失败");
});
 
const pFast = new Promise((resolve, reject) => {
  setTimeout(reject, 100, "很快失败");
});
 
Promise.any([pErr, pSlow, pFast]).then((value) => {
  console.log(value);
}).catch((aggregateError) => {
   console.log(aggregateError.errors);
});
 
 
链式回调
https://segmentfault.com/a/1190000010420744
then回调:then方法提供一个供自定义的回调函数
- 若传入非函数,则会忽略当前then方法
- 回调函数中会把上一个then中返回的值当做参数值供当前then方法调用
- then方法执行完毕后需要返回一个新的值给下一个then调用(没有返回值默认使用undefined)
- 每个then只可能使用前一个then的返回值
 
 
- val接收到的是上一个then或者Promise的结果
- res是被返回并传递给下一个then作为它的参数
let p = new Promise((resolved, rejected) => {
  resolved(1)
})
let p1 = p.then(
  (val) => {
    console.log(val)
    let res = "child";
    return res;
  }
)
p1.then(
  (val) => {
    console.log(val)
  }
)
// 1
// child
具体使用1:then是否是函数
let func = function() {
  return new Promise((resolve, reject) => {
    resolve('返回值');
  });
};
let cb = function() {
  return '新的值';
}
// 有返回值
func().then(function () {
  return cb();
}).then(resp => {
  console.warn(resp);
  console.warn('1 =========<');
});
 
 
// 无返回值
func().then(function () {
  cb();
}).then(resp => {
  console.warn(resp);
  console.warn('2 =========<');
});
 
 
// cb()执行后返回的并不是一个函数
// 在Promise规范中会自动忽略调当前then
// 会把func中的返回值供下一个then使用
func().then(cb()).then(resp => {
  console.warn(resp);
  console.warn('3 =========<');
});
 
 
// 第一个方法在回调内部返回cb执行后的值
// 第四个方法则直接把cb当做回调
func().then(cb).then(resp => {
  console.warn(resp);
  console.warn('4 =========<');
});
 
 
具体使用2:reject和catch
- reject后的东西,一定会进入- then中的第二个回调,如果- then中没有写第二个回调,则进入- catch
- resolve的东西,一定会进入- then的第一个回调,肯定不会进入- catch
- 仅仅返回一个Error对象并不会使Promise变为rejected状态
- 为了真正拒绝一个Promise,需要throw一个错误或调用reject()函数
new Promise((resolve, reject) => {
  resolve('请求成功了');
})
.then((value) => {
  console.log(value);
  return new Error('错误');
})
.catch(() => {
  console.log('错误'); //未打印,发生穿透
})
.then((value) => {
  console.log(111);
})
.then((value) => {
  console.log(222);
})
 
 
- 除非catch()再次抛出错误,否则链中之后的任何then()块都将按正常顺序执行,因为catch()会把Promise的状态从rejected转变为fulfilled
new Promise((resolve, reject) => {
  resolve('请求成功了');
})
.then((value) => {
  console.log(value);
  throw new Error('错误');
})
.catch(() => {
  console.log('错误');
})
.then((value) => {
  console.log(111);
})
.then((value) => {
  console.log(222);
})
 
                


















