zoukankan      html  css  js  c++  java
  • ES6中Promise方法详解

    image

    概要

    Promise是个保存异步结果的容器(对象)。
    Promise的状态有:pending(进行中),fulfilled(已成功),rejected(已失败),对应其异步操作的状态。
    状态转换:

    • pending->fulfilled,将调用resolve函数。
    • pending->rejected,将调用reject函数。

    只能是已上的状态的转换,且其状态的改变只能由其自身改变,状态确定后将不能再改变,此时状态称已定型resolved(参数中常将resolved当作是到fulfilled态)。且Promise对象一旦创建就无法中途取消。

    // 构造函数
    const promise = new Promise(function(resolve, reject) {}
    
    // Promise对象的简单例子。
    function timeout(ms) {
      return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, 'done');
      });
    }
    
    timeout(100).then((value) => {
      console.log(value);
    });
    

    一个Promise对象的组成:
    image

    Promise.prototype.then()

    promise实例可以使用then方法,指定异步成功(resolve)或失败reject时的回调。
    它有两个可以选参数,一参是,resolve的回调,二是reject的回调。then方法返回的是一个新的Promise实例,所以可以再此上继续then,也就是说可以链式操作。

    promise.then(function(value){
      // 成功时调用
    },function(error){
      // 失败时调用
    });
    
    // 链式使用
    const p = Promise.resolve(1);
    
    console.log( p.then(value => console.log("first:"+value)))
    // Promise {<pending>}
    
    p.then(
    value => console.log("first:"+value)
    ).then(
    value => console.log("second:"+value)
    )
    // first:1
    // second:undefined
    

    Promise.prototype.catch()

    catch()方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

    一般来说,不要在then()方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

    promise.then(
    value => console.log("first:"+value)
    ).catch( error => consle.log('错误:'+error) )
    

    注:Promise 内部的错误不会影响到 Promise 外部的代码,Promise中的错误不会让脚本停止运行,通俗的说法就是“Promise 会吃掉错误”。

    Promise.prototype.finally()

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

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

    Promise.all()

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

    const p = Promise.all([p1, p2, p3]);
    

    它的状态由其参数中的,promise中的状态决定:

    • 当传入的全部实例中的状态都fulfilled时,其生成的实例的状态会fulfilled,且传入promise实例的结果组成的数组,会作为当前新实例的回调参数返回。
    • 当参数中实例中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

    若传入的的参数中有不时promise实例的,会调用Prmoise.solve()将其转换成Promise

    Promise.race()

    race()方法同样是将多个Promise实例,包装成一个新的 Promise 实例。

    const p = Promise.race([p1, p2, p3]);
    

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

    Promise.allSettled()

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

    这是一个关注结果,而不关注过程的函数,当前传入参数的实例都有结果时,它的会返回一个fulfilled状态的新实例。

    Promise.any()

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

    Promise.solve()

    该方法可以参生Promise实例,或是将其它对象包装成Promise实例。

    Promise.solve('foo');
    // 等价
    new Promise( function(resolve){ resolve('foo') } )
    

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

    1. 参数是一个 Promise 实例
      此时将不做任何修改、原封不动地返回这个实例。
    2. 参数是一个thenable对象
      thenable对象指的是具有then方法的对象,比如下面这个对象。
    let thenable = {
      then: function(resolve, reject) {
        resolve(42);
      }
    };
    

    Promise.resolve()方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then()方法。

    1. 参数不是具有then()方法的对象,或根本就不是对象
      如果参数是一个原始值,或者是一个不具有then()方法的对象,则Promise.resolve()方法返回一个新的 Promise 对象,状态为resolved。
    const p = Promise.resolve('Hello');
    
    p.then(function (s) {
      console.log(s)
    });
    
    1. 无参数
      Promise.resolve()方法允许调用时不带参数,直接返回一个resolved状态的 Promise 对象。

    Promise.reject()

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

    实例

    Promise对象实现的 Ajax 操作的例子

    const getJSON = function(url) {
      const promise = new Promise(function(resolve, reject){
        const handler = function() {
          if (this.readyState !== 4) {
            return;
          }
          if (this.status === 200) {
            resolve(this.response);
          } else {
            reject(new Error(this.statusText));
          }
        };
        const client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();
      });
      return promise;
    };
    
  • 相关阅读:
    .NET中string和StringBuilder的区别
    Hashtable 类
    C#中null和""的区别
    Dictionary 泛型类
    宿主进程含义
    事件和委托
    关于SQLServer中索引使用及维护简介
    什么是序列化
    “锁定”语句(C# 参考)
    栈和托管堆/值类型和引用类型/强制类型转换/装箱和拆箱[C#]
  • 原文地址:https://www.cnblogs.com/flytree/p/14728030.html
Copyright © 2011-2022 走看看