Promise学习

73 阅读5分钟

1:简介

es6提供的异步编程解决方案,可以将promise看成一个异步操作容器

2:特点

2.1:promise对象有三种状态,pending(默认状态,进行中),fulfilled(成功),rejected(失败)
2.2:状态一经改变,便不可逆

3:缺点

3.1:创建立即执行,无法取消,不设置回调函数,Promise内部抛出的错误无法反应到外部 3.2:当处于pending状态时,无法得知目前进展

4:基本用法

4.1Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供

4.2:resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),

4,3:reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),

5:Promise实例then方法

5.1Promise 实例添加状态改变时的回调函数。then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

5.2Promise实例then方法,返回新的Promise实例默认为成功状态,then方法函数或catch方法函数和设置的返回值,会作为新的Promise实例then方法参数

let p1 = new Promise((reslove,reject)=>{
        setTimeout(()=>{
            reject('0')
        },3000)
    })
    const p2 = p1.then(res=>{
        console.log('p1success',res);
    }).catch(err=>{
        console.log('p1fail',err);
        return Promise.reject(err)
    })
    p2.then(res=>{  
        console.log('p2success',res);
    }).catch(err=>{
        console.log('p2fail',err);
    })

5.3:Promise实例then方法,设置了返回值会被返回的新的Promise实例接收,

let p1 = new Promise((reslove,reject)=>{
   reslove(1)
})
const p2 = p1.then(res=>{
   return res
})
p2.then(res=>{
   console.log(res); //1
})

6:Promise实例catch方法

异步操作抛出错误,状态就会变为rejected,就会调用catch()方法指定的回调函数,

const promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error);
});

如果Promise状态已改变为resloved则抛出错误无效,因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了

const promise = new Promise(function(resolve, reject) {
  resolve('ok');
  throw new Error('test');
});
promise
  .then(function(value) { console.log(value) })
  .catch(function(error) { console.log(error) });
// ok

then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获```

promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

Promise 对象抛出的错误不会传递到外层代码,即不会有任何反应,Promise 会吃掉错误

const someAsyncThing = function() {
  return new Promise(function(resolve, reject) {
    // 下面一行会报错,因为x没有声明
    resolve(x + 2);
  });
};

someAsyncThing().then(function() {
  console.log('everything is great');
});

setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123

6:Promise实例finally方法

finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

finally方法的回调函数不接受任何参数,表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果

7:Promise静态all方法

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例,接受一个数组作为参数,p1p2p3都是 Promise 实例

// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
  return getJSON('/post/' + id + ".json");
});

Promise.all(promises).then(function (posts) {
  // ...
}).catch(function(reason){
  // ...
});

7.1:只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数

    let p1 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reslove('p1成功了')
      },1000)
    })
    let p2 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reslove('p2成功了')
      },2000)
    })
    let p3 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reslove('p3成功了')
      },2000)
    })
    const res = Promise.all([p1,p2,p3])
    res.then(res=>{
      console.log(res); //['p1成功了', 'p2成功了', 'p3成功了']
    }).catch(err=>{
      console.log(err);
    })

7.2:只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数

    let p1 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reslove('p1成功了')
      },1000)
    })
    let p2 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reject('p2失败了')
      },2000)
    })
    let p3 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reslove('p3成功了')
      },2000)
    })
    const res = Promise.all([p1,p2,p3])
    res.then(res=>{
      console.log(res);
    }).catch(err=>{
      console.log(err); // p2失败了
    })

8:Promise静态race方法

Promise.race()参数 数组[]多个promise实例,返回新的 Promise 实例

只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数

9:Promise静态any方法

Promise.any()方法。该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回

只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态

    let p1 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reslove('p1成功了')
      },1000)
    })
    let p2 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reject('p2失败了')
      },2000)
    })
    let p3 = new Promise((reslove,reject)=>{
      setTimeout(function () {
        reslove('p3成功了')
      },500)
    })
    const res = Promise.any([p1,p2,p3])
    res.then(res=>{
      console.log(res); // P3成功了
    }).catch(err=>{
      console.log(err);
    })

10:Promise.resolve()静态方法

1:如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

    let p1 = new Promise((reslove,reject)=>{
      resolve('成功了')
    })
    const res = Promise.resolve(p1)
    console.log(res===p1); // true

2:参数是一个原始值,或者是一个不具有then()方法的对象,则Promise.resolve()方法返回一个新的 Promise 对象,状态为resolved

const p = Promise.resolve('Hello');

p.then(function (s) {
  console.log(s)
});
// Hello

11:Promise.reject()

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

const p = Promise.reject('出错了');
// 等同于
const p = new Promise((resolve, reject) => reject('出错了'))

p.then(null, function (s) {
  console.log(s)
});

11:Promise.## allSettled()