Promise 对象

175 阅读3分钟
  1. Promise 的含义
  2. 基本用法
  • Promise.prototype.then()
  • Promise.prototype.catch()
  • Promise.prototype.finally()
  • Promise.all()
  • Promise.race()
  • Promise.allSettled()
  • Promise.any()
  • Promise.resolve()
  • Promise.reject()
  1. 应用
  • Promise.try()
  1. 阮一峰 参考文章

含义

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

特点

  • 对象的状态不受外界影响。Promise代表异步,三个状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。异步操作才能决定为哪一个状态,其他无效。Promise由来,承诺,表示其他手段无法改变。
  • 一旦状态改变,就不会再变。Promise对象的状态改变,只有两种可能,pending变为fulfilledpending变为rejected。只要改变,会一直保持这个结果。
  • 一旦建立就会立即执行,无法取消。

用法

    let promise = new Promise( function (resolve, reject ){
        console.log(" Promise ") ;
        if( /* 异步操作成功*/){
            resolve(value)
        } else {
            reject(error)
        }
    })
    
    promise.then(function(res){
        // res  fulfilled
        console.log('resolved')
    }, function(error){
        // error rejected
    })
    
    console.log('Hi') ;
    
    三个console.log执行顺序:
        Promise Hi resolved 
  • Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
  • then 方法接收两个回调函数作为参数, 参数1: resolve 参数2: rejected,第二个参数可选
  • promise 新建后会立即执行,因此上面代码,首先执行Promise,然后, then 方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出

使用: 图片加载的异步操作

   function loadImageAsync(url) {
     return new Promise(function(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;
     });
   }

执行顺序

    new Promise((resolve, reject) => {
      resolve(1);
      console.log(2);
    }).then(r => {
      console.log(r);
    });
    
    //result: 2  1

一般来说,调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。

then/catch

    getJSON("/posts.json").then(function(json) {
      return json.post;
    }).then(function(post) {
      // ...
    });
    
    getJSON('/posts.json').then(function(posts) {
      // ...
    }).catch(function(error) {
      // 处理 getJSON 和 前一个回调函数运行时发生的错误
      console.log('发生错误!', error);
    });

finally / all

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

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

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

    const p = Promise.all([p1, p2, p3]);
  1. 上面代码中Promise.all() 接受一个数组作为参数。

  2. p的状态由p1、p2、p3决定,分成两种情况。

  • 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

  • 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。