• Promise笔记


    参考:阮一峰es6(http://es6.ruanyifeng.com/#docs/promise)

    时间:2018-07-03

    类型:个人笔记

    解决的问题:异步编程的一种解决方案。

    定义:Promise是一个保存着未来才会执行的事件的容器,创建后就会执行,但它有resolve和reject,作为未来会执行的事件,等Promise实例执行才会调用。

    形式

     1 //定义一个Promise实例
     2 const promise=new Promise(function(resolve,reject){
     3    console.log('我是Promise内同步的');
     4    setTimeout(function(){
     5        console.log('我是定时器')
     6    },1) 
     7     resolve();
     8 })
     9 //执行promise
    10 promise.then(function(){
    11     console.log('我是resolve')
    12 });
    13 console.log('我是同步的2')

    分析:Promise创建,内部的同步会立即执行,所以输出:

    我是Promise内同步的”  “我是同步的2”

    然后执行异步:一个定时器和promise实例的resolve,定时器本身就是在同步执行完才执行的,promise.then执行后定时器开始执行;

    接着会输出:“我是resolve” “我是定时器”

    写到这里其实和异步没有任何关系,所以来个异步请求开开眼

     1 //Promise干倒Ajax
     2 const getJSON=function(url){
     3     const anyName=new Promise(function(resolve,reject){
     4         const xhr=new XMLHttpRequest();
     5         xhr.open('GET',url);
     6         xhr.onreadystatechange=handler;
     7         xhr.send();
     8         const handler = function() {
     9             if(xhr.readyState!==4){
    10                 return;
    11            }
    12             if (xhr.status ===200) {
    13                 resolve(xhr.response)
    14             }else{
    15                   reject(new Error(xhr.statusText))
    16             }
    17         }
    18     })
    19     return anyName;
    20 }
    21 getJSON('我是路径url').then(function(json){
    22     console.log(json+'是Promise实例anyName执行成功resolve传过来的')      
    23 },function(error){
    24     console.error('出错了',error)
    25 })

    胡乱分析:上述代码的目的是用Promise封装一个Ajax,为撒呢,假如有时候我们需要某一段代码的执行是在异步之后返回结果执行,这样写就不用把代码写在success或者失败里,把成功或者失败分别封装在resolve或者reject,then里的函数就是指这两个。

    特点

    1.Promise有三种状态:pending(在进行)resolve(成功)reject(失败)

    2.状态一旦改变,就不会在变。除非你修改代码,刷新重新加载。(我很认真)

    简记:(简单记忆)

      

    const anyNamePromise = new Promise(function(resolve,reject){
        ***我是异步代码***;
        //判断异步返回状态
        if (status ===200 ){
            //成功了呗,保存成功之后要执行的函数
            resolve('我是要传的参数')
        }else{
            //失败了呗,保存失败要执行的函数
            reject('没啥,哥告诉你咋错的')
        }
    })
    //告诉你怎么调用resolve和reject,不然不是干瞪眼(不是打牌那个,不要打牌,娱乐也不要)
    anyNamePromise.then(function('resolve传过来的'){
        //少侠可以在这里写成功后的要执行的
    },function('我也是传过来的'){
        //不得不说你猜对了,这里是失败后要执行的
    })
    //骚等,会不会觉得这样写不太好看,再来一种写法,这个比较常用
    anyNamePromise.then(function(){}).catch(function(error){})
    //Promise东西好多啊,继续写,emmm

    扩展

    1.resolve的参数除了正常点的值外还可以是另一个Promise实例:

    const p1=new Promise(function(resolve,reject){
         setTimeout(()=>{reject(new Error('fail'))},2)
    })
    const p2=new Promise(function(resolve,reject){
        setTimeout(()=>{resolve(p1)},2)
    })
    p2.then(function(){}).catch(function(){})

    解析:p1的状态决定p2的状态;p2会等着p1状态变为成功或者失败再决定自己的状态;

    2.then

    then返回的是一个新的promise实例,then后还可以.then,前一个then return回的值可以被当前的then作为参数传递使用,前一个then的状态变化,决定后续执行成功还是失败的then

    1 getJSON('url')
    2     .then(()=>{getJSON('newURl')})
    3     .then(()=>{},()=>{})

    3.catch

    处理错误

    p.then(()=>{})
        .catch(()=>{});
    等价于
    p.then(()=>{},()=>{})

    优先使用catch,因为catch也会把then执行的错误也捕获,catch后.catch会把前一个catch的错误捕捉;和try catch不同,Promise对象抛出的错误不会传递到外部,即不会有任何反应

    1 function getFn(){
    2     return new Promise((resolve,reject)=>{
    3         resolve(x+3)
    4     })
    5 }
    6 getFn().then(()=>{console.log('haha')});
    7 setTimeOut(()=>{console.log('jh')},4)

    解析:Promise内部虽然没有声明x会报错,但并不影响后面定时器的执行,错误被Promise吃了

    建议:Promise后跟着catch方法,处理Promise内部的错误。catch方法返回的还是个Promise对象,也可以接着调用then。

    4.finally

    2018引入的

    promise
        .then(()=>{})
        .catch(()=>{})
        .finally(()=>{})

    finally最后都会被执行,不接受任何参数;

    5.all

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

    解析:p1,p2,p3是Promise实例,p的状态仅当p1,p2,p3都为resolve才resolve,此时p1,p2,p3的值会组成数组返回给p;

             只要有一个rejected,p就会变成rejected,此时第一个被rejected的值传回给p

    const promises=[2,3,4].map(function(val){
       return getJSON('url'+val) 
    })
    Promise.all(promises)
        .then(posts=>{console.log(posts)})
        .catch((err)=>{console.log(err)})

     若p1,p2,p3有catch,则返回均为resolve,因为若rejected则会被catch捕获,返回一个新的promise实例,状态resolved。

    6.race

     1 const p=Promise.race([p1,p2,p3])
     2 //例子
     3 const p=Promise.race([
     4     fetch('随意实例'),
     5     new Promise((resolve,reject){
     6         setTimeout(()=>{reject(new Error('hello'))},10)
     7     })
     8 ]);
     9 p
    10     .then(console.log('hoi'))
    11     .catch(console.error);

    竞赛执行

    9.应用

    加载图片

    const preImgLoad=function(url){
        const promise = new Promise((resolve,reject)=>{
            let img = new Image();
            img.src=url;
            img.onload=resolve;
            img.onerror=reject;
        })  
    }
    

      总结:promise里包含着一个异步执行的结果,成功或者失败,成功resolve和失败reject两个函数对应异步结果。一般.then后.catch捕获错误,Promise可以把错误吃了。race和all是多个Promise实例执行,race是竞赛,谁先执行完返回谁,all是返回最后结果,若都resolve,则返回结果放在数组里传给all,catch后返回的是一个新的Promise实例,其状态由catch本身决定。finally无论怎样都会执行的。

  • 相关阅读:
    [Windows Azure] How to Scale a SQL Database Solution
    [Windows Azure] Monitoring SQL Database Using Dynamic Management Views
    [Windows Azure] Managing SQL Database using SQL Server Management Studio
    [Windows Azure] How to Deploy a Database to Windows Azure
    [Windows Azure] How to Create and Configure SQL Database
    [Windows Azure] Guidelines for Connecting to Windows Azure SQL Database
    [Windows Azure] Development Considerations in Windows Azure SQL Database
    [Windows Azure] Management REST API Reference
    [Windows Azure] Windows Azure SQL Database library
    [Windows Azure] Getting Started with Windows Azure SQL Data Sync
  • 原文地址:https://www.cnblogs.com/shui1993/p/9253264.html
Copyright © 2020-2023  润新知