一、Promise是什么?

Promise 是异步编程的一种解决方案: 从语法上讲,promise是一个对象,从它可以获取异步操作的消息;从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
 
回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称——回调地狱
const request = url => {
    return new Promise((resolve, reject) => {
        $.get(url, data => {
            resolve(data)
        });
    })
};

// 请求data1
request(url).then(data1 => {
    return request(data1.url);
}).then(data2 => {
    return request(data2.url);
}).then(data3 => {
    console.log(data3);
}).catch(err => throw new Error(err));

  

promise是用来解决两个问题的:

  • 回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
  • promise可以支持多个并发的请求,获取并发请求中的数据
  • 这个promise可以解决异步的问题,本身不能说promise是异步的

promise的三种状态

var p1 = new Promise(function(resolve,reject){
  resolve(1);
});
var p2 = new Promise(function(resolve,reject){
  setTimeout(function(){
    resolve(2);
  }, 500);
});
var p3 = new Promise(function(resolve,reject){
  setTimeout(function(){
    reject(3);
  }, 500);
});

console.log(p1);
console.log(p2);
console.log(p3);
setTimeout(function(){
  console.log(p2);
}, 1000);
setTimeout(function(){
  console.log(p3);
}, 1000);

p1.then(function(value){
  console.log(value);
});
p2.then(function(value){
  console.log(value);
});
p3.catch(function(err){
  console.log(err);
});

  控制台输出:

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
1
2
3
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}

  

二、es6 promise用法大全

Promise是一个构造函数,自己身上有 all, reject, resolve 这几个眼熟的方法,原型上有 then, catch 等方法。

let p = new Promise((resolve, reject) => {
    //做一些异步操作
    setTimeout(() => {
        console.log('执行完成');
        resolve('我是成功!!');
    }, 2000);
});

  

Promise的构造函数接收一个参数:函数,并且这个函数需要传入两个参数:
  • resolve :异步操作执行成功后的回调函数
  • reject:异步操作执行失败后的回调函数

then 链式操作的用法

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

p.then( (data) => {
   console.log(data);
})
.then( (data) => {
   console.log(data);
})
.then( (data) => {
   console.log(data);
});

  

reject的用法 :

把Promise的状态置为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。看下面的代码。

   let p = new Promise((resolve, reject) => {
        //做一些异步操作
      setTimeout(function(){
            var num = Math.ceil(Math.random()*10); //生成1-10的随机数
            if(num<=5){
                resolve(num);
            }
            else{
                reject('数字太大了');
            }
      }, 2000);
    });
    p.then((data) => {
            console.log('resolved',data);
        },(err) => {
            console.log('rejected',err);
        }
    );

  

then中传了两个参数,then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。
所以我们能够分别拿到他们传过来的数据。多次运行这段代码,你会随机得到下面两种结果:
或者

catch的用法

我们知道Promise对象除了then方法,还有一个catch方法,它是做什么用的呢?

其实它和then的第二个参数一样,用来指定reject的回调。用法是这样:

p.then( (data) => {
  console.log('resolved' , data)
}). catch( (err) => {
  console.log('rejected' , err)
})

效果和写在then的第二个参数里面一样,不过它还有第二个作用: 在执行resolve的回调(也就是上面then中的第一个参数)时,如果抛出异常(代码出错了),那么并不会报错卡死js,而是会进入到这个catch方法中。

p.then( (data) => {
  console.log('resolved', data);
  console.log(somedata);//此处的somedata的定义
})
.catch( (err) => {
  console.log('rejected', err)
})

在resolve的回调中,我们console.log(somedata);而somedata这个变量是没有被定义的。如果我们不用Promise,代码运行到这里就直接在控制台报错了,不往下运行了。但是在这里,会得到这样的结果:

也就是说进到catch方法里面去了,而且把错误原因传到了reason参数中。即便是有错误的代码也不会报错了,这与我们的try/catch语句有相同的功能

all的用法:谁跑的慢,以谁为准执行回调。

all接收一个数组参数,里面的值最终都算返回Promise对象

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完成才执行回调。

看下面的例子:

let Promise1 = new Promise( function(resolve, reject) { });
let Promise2 = new Promise( function(resolve, reject) { });
let Promise3 = new Promise( function(resolve, reject) { });

let p = Promise.all( [Promise1, Promise2, Promise3] )

p.then(function() {
  //三个都成功则成功
},{
  //只要有失败,则失败
})

 

race的用法:谁跑的快,以谁为准执行回调

race的使用场景:比如我们可以用race给某个异步请求设置超时时间,并且在超时后执行相应的操作,代码如下:

   //请求某个图片资源
   function requestImg(){
     var p = new Promise( (resolve, reject) => {
     img.onload = function(){
       resolve(img);
     }
     img.src = '图片的路径';
     });
     return p;
   }

   //延时函数,用于给请求计时
   function timeout() {
     var p = new Promise( (resolve, reject) => {
       setTimeout( () => {
         reject('图片请求超时');
       },5000)
     });
     return p;
   }
   Promise.race([requestImg(), timeout()].then( (data) =>{
     console.log(data);
   }).catch( (err) => {
     console.log(err);
   })
   )

es6 promise 所见的更多相关文章

  1. Es6 Promise 用法详解

     Promise是什么??    打印出来看看  console.dir(Promise) 这么一看就明白了,Promise是一个构造函数,自己身上有all.reject.resolve这几个眼熟的方 ...

  2. 通过 ES6 Promise 和 jQuery Deferred 的异同学习 Promise

    Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同.不过它们的作用可以简单的用两句话来描述 Deffered 触发 resolve ...

  3. ES6 Promise 接口

    构造函数 new Promise(function(resolve, reject){}); 构造函数接受一个函数(executor)作为参数,该函数在返回 Promise 实例之前被调用.函数的两个 ...

  4. ES6 Promise 全面总结

    转载:点击查看原文 ES6 Promise对象 ES6中,新增了Promise对象,它主要用于处理异步回调代码,让代码不至于陷入回调嵌套的死路中. @-v-@ 1. Promise本质 Promise ...

  5. ES6 Promise 异步操作

    最近越来越喜欢与大家进行资源分享了,并且及时的同步到自己的园子内,为什么呢? 一.小插曲(气氛搞起) 在上个月末,由于领导的高度重视(haha,这个高度是有多高呢,185就好了),走进了公司骨干员工的 ...

  6. 微信小程序Http高级封装 es6 promise

    公司突然要开放微信小程序,持续蒙蔽的我还不知道小程序是个什么玩意. 于是上网查了一下,就开始着手开发..... 首先开发客户端的东西,都有个共同点,那就是  数据请求! 看了下小程序的请求方式大概和a ...

  7. 解析ES6 Promise

    ES6 Promise 概念之类的,大概读者都应该有所知道,接下来我们直入终点. 先让我们来看看什么是Promise吧,他是一个object,类,arry,function? 首先,学习它的时候应该讲 ...

  8. jquery Promise和ES6 Promise的区别

    1. Deferred对象有resolve和reject方法,可以直接修改状态 jquery用Deferred实现了Promise规范,Deferred与ES6 Promise的最大区别是: Defe ...

  9. ES6 Promise对象then方法链式调用

    then()方法的作用是Promise实例添加解决(fulfillment)和拒绝(rejection)状态的回调函数.then()方法会返回一个新的Promise实例,所以then()方法后面可以继 ...

随机推荐

  1. centos7修改主机名的方法

    在CentOS7中,有三种定义的主机名: 静态的(Static hostname) “静态”主机名也称为内核主机名,是系统在启动时从/etc/hostname自动初始化的主机名. 瞬态的(Tansie ...

  2. Spring Boot 项目的 API 接口防刷

    首先是写一个注解类 拦截器中实现 注册到springboot中 在Controller中加入注解 说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springbo ...

  3. [转帖]Linux超级用户root口令忘记怎么办?

    Linux超级用户root口令忘记怎么办? 2010-05-10 12:15:00 monkey_d_meng 阅读数 5535  收藏 更多 分类专栏: Linux   版权声明:本文为博主原创文章 ...

  4. setdefault函数的用法及理解

    setdefault函数的用法及理解 dict.setdefault(key, default=None) 功能:如果键不存在于字典中,将会添加该键并将default的值设为该键的默认值,如果键存在于 ...

  5. 2019-7-17 正则表达式和re模块

    一.re模块与正则表达式之间的关系 正则表达式不是python独有的,它是一门独立的技术 所有的编程语言都可以使用正则 但是如果你想在python中使用,你就必须依赖于re模块 正则的官方定义:正则表 ...

  6. Python知识点总结篇(二)

    列表 列表:一个值,包含多个字构成的序列,用[ ]括起来,[]是一个空列表,不包含任何值,类似于空字符串,负数下标表示从后边开始,-1表示列表最后一个下标,它是一种可变的数据类型,值可以添加.删除或改 ...

  7. DISPLAY FORMAT 語法

  8. golang基础学习-strings包常用函数学习

    package main import ( "fmt" "strings" ) //StrFunc 字符串说明 func main() { var testSt ...

  9. JavaScript之DOM节点操作

    a.appendChild(b)  追加标签 a是b的父级,将b追加到a中 追加标签  a.insertBefore(b,c);  a是b和c的父级,在c前面插入b 删除标签  a.removeCli ...

  10. wamp环境下配置https证书后,网站内容访问受限

    wamp环境下配置https证书后,网站内容访问受限,点击首页链接标签后报错,大致意思是没有权限进行操作. 解决方法:打开apache的http.conf(位置大致如下:项目所在目录\bin\apac ...