ES6异步操作Promise

什么是Promise

Promise是异步编程的一种解决方案,说白了就是一个构造函数,带有all,reject,resolve这几个方法,圆形上有then,catch等方法

Promise的特点

  • 对象的状态不受外界影响,他的对象代表的是一个异步操作,只有三种状态,pending(进行中)fulfilled(已成功)rejected(已失败)只有异步操作可以决定当前是哪一种状态,其他任何操作都无法改变这个状态,这也是Promise这个名字的由来,翻译成中文就是承诺的意思,表示一旦对象生成,其他手段都无法改变。
  • 一旦状态发生改变,就不会再便,任何时候都可以得到这个结果。Promise对象的状态改变只有两种可能,从pending变为fullfilled以及从pending变为rejected 只要这两种情况发生,状态就定死了,不会在改变了,就会一直保持这个结果,这事就成为resolve(定形完成),如果状态已经发生了,在对Promise对象添加回调函数,也会立即得到这个结果。这个与event完全不一样,event的特点是如果错过了事见再去监听这个event事见,是得不到这个结果的

    Promise的用法

    我们先创建一个Promise

let e = new Promise (function (resolve,reject){
    settimeout (function(){
        console.log('执行完成Promise')
        resolve('此处执行当请求完成后 Promise返回的结果')
    },2000)
})

其执行过程是:执行了一个异步操作,也就是setTimeout,2秒后,输出“执行完成”,并且调用resolve方法。

注意!我只是new了一个对象,并没有调用它,我们传进去的函数就已经执行了,这是需要注意的一个细节。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数,如:

<div onClick={promiseClick}>开始异步请求</div>

const promiseClick =()=>{
     console.log('点击方法被调用')
     let p = new Promise(function(resolve, reject){
        //做一些异步操作
        setTimeout(function(){
                console.log('执行完成Promise');
                resolve('要返回的数据可以任何数据例如接口返回数据');
            }, 2000);
        });
        return p
    }

放在函数里面的时候只有调用的时候才会被执行

那么,接下里解决两个问题:

1、为什么要放在函数里面

2、resolve是个什么鬼

我们包装好的函数最后,会return出Promise对象,也就是说,执行这个函数我们得到了一个Promise对象。接下来就可以用Promise对象上有then、catch方法了,这就是Promise的强大之处了,看下面的代码:


promiseClick().then(function(data){
    console.log(data);
    //后面可以用传过来的数据做些其他操作
    //......
});

先是方法被调用起床执行了promise,最后执行了promise的then方法,then方法是一个函数接受一个参数是接受resolve返回的数据这事就输出了‘要返回的数据可以任何数据例如接口返回数据’

这时候你应该有所领悟了,原来then里面的函数就跟我们平时的回调函数一个意思,能够在promiseClick这个异步任务执行完成之后被执行。这就是Promise的作用了,简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。

你可能会觉得在这个和写一个回调函数没有什么区别;那么,如果有多层回调该怎么办?如果callback也是一个异步操作,而且执行完后也需要有相应的回调函数,该怎么办呢?总不能再定义一个callback2,然后给callback传进去吧。而Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。

所以:精髓在于:Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。所以使用Promise的正确场景是这样的:


promiseClick()
.then(function(data){
    console.log(data);
    return runAsync2();
})
.then(function(data){
    console.log(data);
    return runAsync3();
})
.then(function(data){
    console.log(data);
});

reject的用法

`以上是对resolve状态是的用法,resolve相当于是对promise成功时候窒息感的回掉函数,状态值修改为fullfiled,,那么,reject就是失败的时候的回调,他把promise的状态修改为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。

function promiseClick(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('数字太于10了即将执行失败回调');
                }
            }, 2000);
           })
           return p
       }

    promiseClick().then(
        function(data){
            console.log('resolved成功回调');
            console.log('成功回调接受的值:',data);
        },
        function(reason, data){
            console.log('rejected失败回调');
            console.log('失败执行回调抛出失败原因:',reason);
        }
    );

以上代码:调用promiseClick方法执行,2秒后获取到一个随机数,如果小于10,我们算成功,调用resolve修改Promise的状态为fullfiled。否则我们认为是“失败”了,调用reject并传递一个参数,作为失败的原因。并将状态改成rejected

运行promiseClick并且在then中传了两个参数,这两个参数分别是两个函数,then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。(也就是说then方法中接受两个回调,一个成功的回调函数,一个失败的回调函数,并且能在回调函数中拿到成功的数据和失败的原因),所以我们能够分别拿到成功和失败传过来的数据就有以上的运行结果

catch用法

catch的用法和结果有点类似于reject,即失败的时候执行的回调函数,主要是用来捕捉异常.


function promiseClick(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('数字太于10了即将执行失败回调');
                }
            }, 2000);
           })
           return p
       }

    promiseClick().then(
        function(data){
            console.log('resolved成功回调');
            console.log('成功回调接受的值:',data);
        }
    )
    .catch(function(reason, data){
        console.log('catch到rejected失败回调');
        console.log('catch失败执行回调抛出失败原因:',reason);
    });

效果和写在then的第二个参数里面一样。它将大于10的情况下的失败回调的原因输出,但是,它还有另外一个作用:在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常了(代码出错了),那么并不会报错卡死js,而是会进到这个catch方法中。如下:

function promiseClick(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('数字太于10了即将执行失败回调');
                }
            }, 2000);
           })
           return p
       }

    promiseClick().then(
        function(data){
            console.log('resolved成功回调');
            console.log('成功回调接受的值:',data);
            console.log(noData);
        }
    )
    .catch(function(reason, data){
        console.log('catch到rejected失败回调');
        console.log('catch失败执行回调抛出失败原因:',reason);

在resolve回调中,我们console.lognodata这个变量 传统的情况下是会报错的,即当代码执行到此处的时候就会抛出错误,浏览器不会继续执行下去。但是以上如果使用了catch,就没有报错并且会得到结果,也就是说进到catch方法里面去了,而且把错误原因传到了reason参数中。即便是有错误的代码也不会报错了

all的用法

与then同级的另一个方法,all方法,该方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后并且执行结果都是成功的时候才执行回调。
将上述方法复制两份并重命名promiseClick3(), promiseClick2(), promiseClick1(),如下


function promiseClick1(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('数字太于10了即将执行失败回调');
                }
            }, 2000);
           })
           return p
       }
       function promiseClick2(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('数字太于10了即将执行失败回调');
                }
            }, 2000);
           })
           return p
       }
       function promiseClick3(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('数字太于10了即将执行失败回调');
                }
            }, 2000);
           })
           return p
       }

    Promise
        .all([promiseClick3(), promiseClick2(), promiseClick1()])
        .then(function(results){
            console.log(results);
        })

Promise.all来执行,all接收一个数组参数,这组参数为需要执行异步操作的所有方法,里面的值最终都算返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后才会进到then里面。那么,三个异步操作返回的数据哪里去了呢?都在then里面,all会把所有异步操作的结果放进一个数组中传给then,然后再执行then方法的成功回调将结果接收,结果如下:(分别执行得到结果,all统一执行完三个函数并将值存在一个数组里面返回给then进行回调输出)

race的用法

race的用法与all相对立,all是等所有的异步操作都执行完了再执行then方法,那么race方法就是相反的,谁先执行完成就先执行回调


function promiseClick1(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('2s随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('2s数字太于10了即将执行失败回调');
                }
            }, 2000);
           })
           return p
       }
       function promiseClick2(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('3s随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('3s数字太于10了即将执行失败回调');
                }
            }, 3000);
           })
           return p
       }
       function promiseClick3(){
        let p = new Promise(function(resolve, reject){
            setTimeout(function(){
                var num = Math.ceil(Math.random()*20); //生成1-10的随机数
                console.log('4s随机数生成的值:',num)
                if(num<=10){
                    resolve(num);
                }
                else{
                    reject('4s数字太于10了即将执行失败回调');
                }
            }, 4000);
           })
           return p
       }

    Promise
        .race([promiseClick3(), promiseClick2(), promiseClick1()])
        .then(function(results){
            console.log(results);
        },function(reason){
            console.log(reason);
        });

race的使用比如可以使用在一个请求在10s内请求成功的话就走then方法,如果10s内没有请求成功的话进入reject回调执行另一个操作。

原文地址:https://www.cnblogs.com/wangjiahui/p/11386312.html

时间: 2024-11-02 14:41:45

ES6异步操作Promise的相关文章

ES6之Promise用法详解

一 前言 本文主要对ES6的Promise进行一些入门级的介绍.要想学习一个知识点,肯定是从三个方面出发,what.why.how.下面就跟着我一步步学习吧~ 二 什么是Promise 首先是what.那么什么是Promise呢? 以下是MDN对Promise的定义 The Promise object is used for asynchronous computations. A Promise represents a single asynchronous operation that

浅谈ES6原生Promise

浅谈ES6原生Promise 转载 作者:samchowgo 链接:https://segmentfault.com/a/1190000006708151 ES6标准出炉之前,一个幽灵,回调的幽灵,游荡在JavaScript世界. 正所谓: 世界本没有回调,写的人多了,也就有了})})})})}). Promise的兴起,是因为异步方法调用中,往往会出现回调函数一环扣一环的情况.这种情况导致了回调金字塔问题的出现.不仅代码写起来费劲又不美观,而且问题复杂的时候,阅读代码的人也难以理解. 举例如下

ES6——异步操作之Promise

基本概念: Promise : 是 ES6 中新增的异步编程解决方案,提现在代码中他是一个对象 可以通过Promise构造函数来实例化. -new Promise(cb) ===> 实例的基本使用,Pending Resolved Rejected > 两个原型方法: -Promise.prototype.then() -Promise.prototype.catch() > 两个常用的 静态方法. -Promise.all(); -Promise.resolve(); conse im

es6异步操作

异步编程对 JavaScript 语言太重要.JavaScript 只有一根线程,如果没有异步编程,根本没法用,非卡死不可. ES6 诞生以前,异步编程的方法,大概有下面四种. 回调函数 事件监听 发布/订阅 Promise 对象 ES6 将 JavaScript 异步编程带入了一个全新的阶段. 基本概念 异步 所谓"异步",简单说就是一个任务分成两段,先执行第一段,然后转而执行其他任务,等做好了准备,再回过头执行第二段. 比如,有一个任务是读取文件进行处理,任务的第一段是向操作系统发

ES6 - promise对象

Promise的设计初衷 我们使用ajax请求数据,得到数据后再对数据进行操作,可是有时候,对得到的数据进行操作的过程中,可能又要用到ajax请求,这时,我们的代码就变成了这样: $.ajax({ success:function(res1){ //...请求B开始,B依赖A返回的数据 $.ajax({ sucess:function(res2){ //...请求C开始,C依赖B返回的数据 $.ajax({ sucess:function(res3){ } }); } }); } }); 这种写

ES6的promise对象应该这样用

ES6修补了一位Js修真者诸多的遗憾. 曾几何时,我这个小白从js非阻塞特性的坑中爬出来,当我经历了一些回调丑陋的写法和优化的尝试之后,我深深觉得js对于多线程阻塞式的开发语言而言,可能有着其太明显的缺点,而又无法忽略的是也正因为这一点,node.js处理并行的能力被人看作优点,在我看来,这其实有着些讽刺的意味,就好像踢足球时有的人总夸你腿短,所以频率快下盘稳好控球...好在js从出生以来就有一种独特的特质,就是模仿,对,就是模仿,模仿别人的优点来补足自己,同时保持自己的长处. ES6就是通过P

ES6的promise的学习

1.Promise的含义: Promise是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.从语法上说,Promise是一个对象,从它可以获取异步操作的消息.Promise提供统一的API,各种异步操作都可以用同样的方法进行处理. Promise对象有以下两个特点. (1)

es6 之 promise 对象

异步编程 传统方案:事件 + 回调函数 ES6 的新方案:Promise 对象 Promise 异步操作有 3 种状态 pending: 进行中 resolved: 已完成 rejected: 已失败 Promise 异步操作的状态变化仅限下面两种方式 pending –> resolved pending –> rejected 创建一个 Promise 实例: promise 构造函数接收一个函数作为参数,并且这个函数有两个参数,这两个参数是也是两个函数,不过这两个函数由 JavaScri

ES6中Promise对象个人理解

Promise是ES6原生提供的一个用来传递异步消息的对象.它减少了传统ajax金字塔回调,可以将异步操作以同步操作的流程表达出来使得代码维护和可读性方面好很多. Promise的状态: 既然是用来传递异步消息的那肯定就会有异步消息的状态:所以promise提供了3种状态:pending(进行中),resolved(已完成或者称 fulfilled),rejected(失败).不同的是Promise不会受外界影响,只有异步操作结果才能决定当前是哪种状态,任何其他非异步操作都不能改变.所以当状态发