• Promise语法


    Promise概述

    Promise对象具有三种状态:

    pending(进行中)

    resolved(已成功)

    rejected(已失败)

    promise内部会封装一个异步操作,当异步完成时,promise的状态就会发生改变,如果异步操作是成功的,状态变为resolved,如果异步操作是失败的,状态会变为rejected

    当promise的状态发生改变,让promise的回调函数进行回调队列(微队列),等待执行。

    没有 promise 的时候,异步操作完成直接让自己的回调函数进入回调队列等待执行;有了 promise 的封装,异步操作执行完毕,改变 promise 的状态,promise 状态改变让 promise 的回调函数进入回调队列等待执行。所以,promise 就是中间商!

    promise基本语法

    ①使用Promise构造函数创建promise对象

    let p=new Promise(()=>{});

    p就是创建的promise对象,初始状态是pending

    Promise参数必须是一个回调函数

    ②修改promise对象的状态

    //需要给Promise的回调函数传参
    let p = new Promise((resolve,reject)=>{
       resolve();//将promise对象状态变为resolved(fulfilled)
    });

    promise 对象的状态一旦改变,就不能在改变了。

    Promise构造函数的参数是回调函数,是同步执行的,实例化过程就执行了

    通过then方法给promise对象指定的回调函数是异步执行的,当promise的状态发生改变,这里的回调函数进入回调队列等待执行。

    ③指定promise对象的回调函数

    let p=new Promsie((resolve,reject)=>{
       //resolve和reject不论先调用谁,调用之后的状态都不会再发生改变
       //调用resolve,把状态改为resolved,该参数会传递给then第一个回调函数
       resolve([4,6,34,3]);
       //调用reject把状态改为rejected,该参数回传给then的第二个回调函数
       reject('连接超时...');
    });

    p.then((value)=>{
       console.log(value);//[4,6,34,3]
    },reason=>{
       console.log(reason);//连接超时...
    })

    可以给promise指定两个回调函数,如果promise对象的状态是resolved,调用第一个回调函数,如果promise的状态是rejected,调用第二个回调函数;

    Promise构造函数的回调函数中,调用resolve和reject的时候可以传递参数,promise对象的回调函数可以接收

    Promise实例的方法

    1. Promise.prototype.then()

    ①参数

    then方法可以指定两个函数,都是回调函数,promise状态如果

    是成功的调用第一个参数,promise对象如果是失败的,调用第二个参数

    ②返回值

    then()方法一定会返回promise对象,所以then方法支持链式调用

    then()方法返回值规则如下:

    1. 如果回调函数没有返回值,then()返回一个成功的promise对象,值是undefined。

    2. 如果回调函数指定返回值(且不是promise对象),then方法返回一个成功状态的promise对象,值是回调函数的返回值。

    3. 如果回调函数中抛出错误,then方法返回一个失败状态的promise对象,失败的reason是错误信息

    4. 如果回调函数是一个promise对象,返回值就是此promise对象

    2.catch方法

    ①参数

    参数指定一个回调函数,promise对象的状态变为失败的时候会调用

    ②then和catch可以配合使用

    let p=new Promise((resolve,reject)=>{
       reject('故意出错');
    });

    p.then(()=>{
       console.log('成功');
    }).catch(reason=>{
       console.log('出错',reason);
    })

    ③异常穿透

    使用 then 进行链式调用的时候,可以只给then指定成功的回调函数,最后通过 catch 兜底,不论哪一步出现异常(状态变为失败),最终都会穿透到 catch ,执行它的回调函数。

      function setTimeoutPromise(delay, value) {
         // 创建 promise 对象并返回
         return new Promise((resolve, reject) => {
             setTimeout(resolve, delay, value);
        });
    }

    setTimeoutPromise(2000).then(() => {
       //取 0 -9 之间随机数
       let rand1 = Math.floor(Math.random() * 10);
       console.log(rand1);
       a; // 异常语法
       // 返回一个 promise 对象
       return setTimeoutPromise(3000, rand1);
    }).then(value => {
       // 取随机数 + value
       let rand2 = Math.floor(Math.random() * 10) + value;
       console.log(rand2);
       // 返回一个 promise 对象

       return setTimeoutPromise(1000, rand2);

    }).then(value => {
       // 取随机数 + value
       let rand3 = Math.floor(Math.random() * 10) + value;
       console.log(rand3);
    }).catch(reason => {
       console.log('错误:', reason);
    })

    3.finally

    接收一个回调函数作为参数,只要promise状态改变,回调函数就调用

    Promise构造函数本身方法

    1.Promise.resolve()

    ①功能

    返回一个promise对象,可以用来快速创建一个promise对象

    ②根据参数不同返回的promise也不同

    1. 如果不给参数,返回一个成功状态的promise对象,值是undefined

    2. 如果给一个值作为参数(不是promise对象也不是thenable对象),返回一个成功状态的 promie 对象,值是参数。

    3. 如果参数是个 promise 对象,直接把这个 promise 对象作为返回值。

    4. 如果参数是一个thenable对象,方法内部会根据then方法创建一个有promise对象并返回

      具有then方法的对象就是thenable对象

      var obj={
         then(resolve,reject){
             reject('老子错了');
        }
      };
      let p4=Promise.resolve(obj);
      // 执行 resolve 方法的时候,内部实例化 Promise 构造函数,把 then 方法作为参数

       

    2 Promise.reject()

    没有 Promise.resolve 那么复杂,就返回一个失败状态的 promie 对象,参数不论是什么数据都会作为返回的promise对象失败原因;没有参数失败原因就是undefined。

    3 Promise.all()

    可以把多个promise对象整合成一个promise对象并返回

    参数是一个数组或者其他可遍历对象,成员都是promise对象(不是promise对象的会自动使用Promise.resolve()创建为promise对象)

    1. 如果传入的所有的promise对象都是成功状态,则返回的promise对象会是所有promise对象的值组成的数组

    2. 一旦有一个 promise 对象变为失败状态,返回的 promise 对象立即变为失败状态!

    Promise 的优势

    1. 回调函数设置方式更加灵活,可以设置多个,可以再任何时刻设置回调函数。

    2. then 方法的链式调用,有效解决回调地狱问题 (回调地狱:回调函数内部嵌套回调函数)

    宏队列和微队列

    事件轮询机制中,回调队列有两个,分别是宏对列和微队列。

    定时器的回调函数、DOM事件的回调函数、Ajax的回调函数会进入宏队列。

    promise对象的回调函数进入微队列。

    当执行栈空了之后,会先把微队列中的回调函数以此取出来执行,等微队列都执行完毕了,才从宏队列中依次取出回调函数执行。

  • 相关阅读:
    洛谷P2640 神秘磁石(欧拉筛法)
    并查集
    高精度算法
    手写堆
    对拍的使用
    unity4.6学习Ugui中文文档-------参考-UGUI Rect Transform
    使用c#访问脚本里变量的方法
    Unity3d 脚本相互调用
    set_union的几个例子[转]
    C++ 关键字——friend
  • 原文地址:https://www.cnblogs.com/xincheng-1999/p/14032790.html
Copyright © 2020-2023  润新知