南辞派

导航

Promise了解

Promise含义

Promise是ES6新增的一种异步编程的解决方案.所谓Promise,简单的说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上来讲,Promise是一个对象,我们可通过它获取异步操作的消息.Promise提供各种方便进行异步操作处理的统一的API.

Promise的特点:

1.对象的状态不受外界影响

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败).这三种状态只受到异步操作结果的影响,通常通过一异步操作的结果来决定是哪一种状态.

2.一旦状态改变,就不会再变,任何时候得到的结果都保持一致.

Promise对象的状态改变,只有两种可能:从pending(进行中)变为fulfilled(已成功)、从pending(进行中)变为rejected(已失败).只要这两种状况发生,状态就固定不再改变,这时就称为resolved(已定型).如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果.这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去进行监听,是得不到结果的.

Promise一旦建立无法取消,当建立Promise后,它就会立即执行.Promise内部抛出的错误,需要我们通过设置回调函数才能进行读取.当Promise处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成).

Promise使用:

const promise=new Promise(function(resolve,reject){
	.....异步操作代码块
	if(/* 异步操作成功 */){
		resolve(value)
	}else{
		reject(error);
	}
});

promise.then(res=>{
    console.log('success')
}).catch(err=>{
    console.log('fail')
}).finally(()=>{
    ...不论是成功还是失败都会执行此处的代码块
})

/* 
ES6规定,Promise的创建通过Promise构造函数进行声明.

Promise构造函数接受一个函数作为参数,该函数又存在两个参数分别为resolve和reject.这两个参数都是函数类型,是javascript引擎默认提供的,不需我们自己构建的.

resolve函数用于当Promise对象的状态从'未完成'转变为'成功'(即从pending->resolved,异步操作成功)时调用,通过将异步操作的成功结果作为参数回调出去.
reject函数用于当Promise对象的状态从'未完成'转变为'失败'(即从pending->rejected状态,异步操作失败)时调用,通过将异步操作失败的提示作为参数传递出去.

当Promise实例生成后,我们可以通过then方法和catch方法分别接受成功状态返回的结果和失败状态返回的错误提示信息.finally方法表示无论成功还是失败都将执行的代码块.
*/

异步加载图片案例:

function loadImageAsync(url) {
     return new Promise((resolve, reject) => {
        const image = new Image();
        image.onload = function () {
            resolve(image);
        };
        image.onerror = function () {
           reject(new Error('Could not load image at ' + url));
        };
        image.src = url;
    });
}
loadImageAsync(
        'https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2776943011,3188085605&fm=26&gp=0.jpg',
)
  .then((res) => {
     document.body.appendChild(res);
   })
  .catch((err) => {
    console.log(err);
   });

Promise对象方法

Promise.all()方法

​ Promise.all()方法用于将多个Promise实例对象组合成一个新的Promise实例,常用于需要同时获取多个Promise实例对象返回值时使用.

​ Promise.all()方法接收一个数组或具有iterator接口的对象作为参数,若数组元素都是Promise实例对象,则直接进行处理.若不是Promise实例对象,则会先进行转换为Promise实例对象,再进行处理.

​ Promise.all()方法返回的数据是Promise实例.

let p1=new Promise((resolve,reject)=>{
	setTimeout(()=>{
        resolve('success 1')
    },1000)
})
let p2=new Promise((resolve,reject)=>{
	setTimeout(()=>{
        resolve('success 1')
    },1000)
})
let p3=new Promise((resolve,reject)=>{
	setTimeout(()=>{
        resolve('success 3')
    },1000)
})

let p=Promise.all([p1,p2,p3]); // 只有所有promise实例对象的状态都是resolve时,p的状态才为resolve状态;若是实例对象中有一个时rejected状态,则p的状态为rejected状态

console.log(p); // 返回结果也是一个Promise实例

Promise.race()方法

Promise.race()方法的作用与Promise.all()方法相同.都是同时调用多个promise实例对象.

不同点在于Promise.race()方法的返回值只受到第一个返回状态的promise实例的影响

即:当有一个实例对象优先返回状态后,Promise.race()方法的状态就固定为这个实例对象的状态,不再受其他实例的影响.

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('success');
      }, 3000);
    });
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(new Error('This is Error message...'));
      }, 2000);
    });
const p3 = new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error('This is Error message p3...'));
        }, 1000);
      });

const p = Promise.race([p1, p2,p3]);
p.then(res=>{
    console.log(res)
}).catch(err=>{ // 因为p3比p1和p2先返回状态 reject(new Error('This is Error message p3...')),因此p的状态为rejected
    console.log(err); // Error: This is Error message p3...
})

Promise.allSettled()方法

Promise.allSettled()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束

该方法返回的新的 Promise 实例,一旦结束,状态总是fulfilled,不会变成rejected。状态变成fulfilled后,Promise 的监听函数接收到的参数是一个数组,每个成员对应一个传入Promise.allSettled()的 Promise 实例。

当我们不关心异步操作的结果,只考虑这些异步操作是否都已经完成时,使用Promise.allSettled()方法是一个十分有效的解决方法.

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('success');
  }, 3000);
});
const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    	reject(new Error('This is Error message p2...'));
      }, 2000);
    });
const p3 = new Promise((resolve, reject) => {
    setTimeout(() => {
       reject(new Error('This is Error message p3...'));
      }, 1000);
    });

const p = Promise.allSettled([p1, p2,p3]);
// 使用Promise.allSettled方法的Promise实例状态只能是fulfilled状态(完成)
p.then((res) => console.log(res))

/**
	Promise.allSettled()方法返回的结果是一个数组对象;
	每个对象都有status属性,该属性的值只可能是字符串fulfilled或字符串rejected。
	当实例对象返回的状态是fulfilled时,对象有value属性;rejected时有reason属性,对应两种状态的返回值。
**/

Promise.any()方法

Promise.any()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只要参数实例有一个变成fulfilled状态,包装实例就会变成优先返回fulfiled状态的实例的fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

const p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('success 2')
          // reject(new Error('This is Error message p1...'));
        }, 3000);
      });
      const p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
          // reject(new Error('This is Error message p2...'));
          resolve('success 1')
        }, 2000);
      });
      const p3 = new Promise((resolve, reject) => {
        setTimeout(() => {
          reject(new Error('This is Error message p3...'));
        }, 1000);
      });
      const p = Promise.any([p1, p2, p3]);
      p.then((res) => console.log(res)).catch((err) => {
        console.log(err);
      });
      
/** 
	当所有的promise实例都返回rejected状态时,p的状态为rejected->AggregateError: All promises were rejected
	当有一个promise实例返回fulfiled状态时,p的状态为最先返回fulfiled状态的实例.
**/

Promise.resolve()方法与Promise.reject()方法

有时需要将现有对象转为 Promise 对象,Promise.resolve()方法和Promise.reject()方法就起到这个作用。

Promise.resolve()方法转换的Promise'对象状态都是resolved状态

Promise.resolve()方法的参数分成四种情况。

(1)参数是一个 Promise 实例

(2)参数是一个thenable对象

(3)参数不是具有then()方法的对象,或根本就不是对象

(4)不带有任何参数

Promise.reject()方法转换的Promise对象状态都是rejected状态.

简单使用:

const p=Promise.resolve('Hello,World');
/** 上述代码等价于 
const p=new Promise((resolve)=>{
	resolve('Hello,world');
)
**/
p.then(res=>console.log(res)); // Hello,world


const p = Promise.reject('出错了');
/** 上述代码等价于
const p = new Promise((resolve, reject) => reject('出错了'))

**/
p.then(null, function (s) {
  console.log(s)
});
// 出错了

posted on 2020-10-26 12:03  HuaiJinCi  阅读(53)  评论(0编辑  收藏  举报