zoukankan      html  css  js  c++  java
  • 学习promise

    promise是什么?

    1、主要用于异步计算(异步操作)
    2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
    3、可以在对象之间传递和操作promise,可以帮助我们处理队列

    为什么会有promise?

    为了避免界面冻结(任务)

    同步:顺序交付的工作1234,必须按照1234的顺序完成”。
    异步:则是将耗时很长的A交付的工作交给系统之后,就去继续做B交付的工作,。等到系统完成了前面的工作之后,再通过回调或者事件,继续做A剩下的工作。
    AB工作的完成顺序,和交付他们的时间顺序无关,所以叫“异步”。

    异步操作的常见语法

    事件监听

    document.getElementById('#start').addEventListener('click', start, false);
    function start() {
      // 响应事件,进行相应的操作
    }
    // jquery on 监听
    $('#start').on('click', start)

    回调

    // 比较常见的有ajax
    $.ajax('http://www.wyunfei.com/', {
     success (res) {
       // 这里可以监听res返回的数据做回调逻辑的处理
     }
    })
    
    // 或者在页面加载完毕后回调
    $(function() {
     // 页面结构加载完成,做回调逻辑处理
    })

    异步回调的问题:

    • 之前处理异步是通过纯粹的回调函数的形式进行处理
    • 很容易进入到回调地狱中,剥夺了函数return的能力
    • 问题可以解决,但是难以读懂,维护困难
    • 稍有不慎就会踏入回调地狱 - 嵌套层次深,不好维护

    promise

    • promise是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(闭包除外)
    • 并未剥夺函数return的能力,因此无需层层传递callback,进行回调获取数据
    • 代码风格,容易理解,便于维护
    • 多个异步等待合并便于解决

    promise详解

     
    new Promise(
      function (resolve, reject) {
        // 一段耗时的异步操作
        resolve('成功') // 数据处理完成
        // reject('失败') // 数据处理出错
      }
    ).then(
      (res) => {console.log(res)},  // 成功
      (err) => {console.log(err)} // 失败
    )
    • resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
      reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
    • promise有三个状态:
      1、pending[待定]初始状态
      2、fulfilled[实现]操作成功
      3、rejected[被否决]操作失败
      当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;
      promise状态一经改变,不会再变。
    • Promise对象的状态改变,只有两种可能:
      从pending变为fulfilled
      从pending变为rejected。
      这两种情况只要发生,状态就凝固了,不会再变了。
    最简单示例:
    new Promise(resolve => {
      setTimeout(() => {
        resolve('hello')
      }, 2000)
    }).then(res => {
      console.log(res)
    })
    分两次,顺序执行
    new Promise(resolve => {
        setTimeout(() => {
          resolve('hello')
        }, 2000)
      }).then(val => {
        console.log(val) //  参数val = 'hello'
        return new Promise(resolve => {
          setTimeout(() => {
            resolve('world')
          }, 2000)
        })
      }).then(val => {
        console.log(val) // 参数val = 'world'
      })
    promise完成后then()
    let pro = new Promise(resolve => {
       setTimeout(() => {
         resolve('hello world')
       }, 2000)
     })
     setTimeout(() => {
       pro.then(value => {
       console.log(value) // hello world
     })
     }, 2000)

    结论:promise作为队列最为重要的特性,我们在任何一个地方生成了一个promise队列之后,我们可以把他作为一个变量传递到其他地方。

    .then()

    1、接收两个函数作为参数,分别代表fulfilled(成功)和rejected(失败)
    2、.then()返回一个新的Promise实例,所以它可以链式调用
    3、当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行
    4、状态响应函数可以返回新的promise,或其他值,不返回值也可以我们可以认为它返回了一个null;
    5、如果返回新的promise,那么下一级.then()会在新的promise状态改变之后执行
    6、如果返回其他任何值,则会立即执行下一级.then()

    .then()里面有.then()的情况

    1、因为.then()返回的还是Promise实例
    2、会等里面的then()执行完,再执行外面的

    错误处理两种做法:
    第一种:reject('错误信息').then(() => {}, () => {错误处理逻辑})
    第二种:throw new Error('错误信息').catch( () => {错误处理逻辑})
    推荐使用第二种方式,更加清晰好读,并且可以捕获前面所有的错误(可以捕获N个then回调错误)

    catch也会返回一个promise实例,并且是resolved状态
     
     
    Promise.all() 批量执行

    Promise.all([p1, p2, p3])用于将多个promise实例,包装成一个新的Promise实例,返回的实例就是普通的promise
    它接收一个数组作为参数
    数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变
    当所有的子Promise都完成,该Promise完成,返回值是全部值得数组
    有任何一个失败,该Promise失败返回值是第一个失败的子Promise结果 

    //切菜
        function cutUp(){
            console.log('开始切菜。');
            var p = new Promise(function(resolve, reject){        //做一些异步操作
                setTimeout(function(){
                    console.log('切菜完毕!');
                    resolve('切好的菜');
                }, 1000);
            });
            return p;
        }
    
        //烧水
        function boil(){
            console.log('开始烧水。');
            var p = new Promise(function(resolve, reject){        //做一些异步操作
                setTimeout(function(){
                    console.log('烧水完毕!');
                    resolve('烧好的水');
                }, 1000);
            });
            return p;
        }
    
        Promise.all([cutUp(), boil()])
            .then((result) => {
                console.log('准备工作完毕');
                console.log(result);
            })
    Promise.race() 类似于Promise.all() ,区别在于它有任意一个完成就算完成
    • 常见用法:
      异步操作和定时器放在一起,,如果定时器先触发,就认为超时,告知用户;
      例如我们要从远程的服务家在资源如果5000ms还没有加载过来我们就告知用户加载失败

    • 现实中的用法
      回调包装成Promise,他有两个显而易见的好处:
      1、可读性好
      2、返回 的结果可以加入任何Promise队列








     
  • 相关阅读:
    mysql数据库常用指令
    解决windows的mysql无法启动 服务没有报告任何错误的经验。
    “Can't open file for writing”或“operation not permitted”的解决办法
    启动Apache出现错误Port 80 in use by "Unable to open process" with PID 4!
    如何打开windows的服务services.msc
    常见的HTTP状态码 404 500 301 200
    linux系统常用的重启、关机指令
    (wifi)wifi移植之命令行调试driver和supplicant
    linux(debian)安装USB无线网卡(tp-link TL-WN725N rtl8188eu )
    alloc_chrdev_region申请一个动态主设备号,并申请一系列次设备号
  • 原文地址:https://www.cnblogs.com/aixue/p/13206788.html
Copyright © 2011-2022 走看看