一、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. python:求整数的二进制表示

    求解方法: 1.整数求余 2.重复进行,整数除2再求余,直到除数为0 3.拼接余数 4.反转字符串 def int2two(intNo): twoStr='' if intNo == 0: twoSt ...

  2. Python输出菱形

    最近准备熟悉下Python的基础语法,准备练习下输出菱形.刚好作为自己blog的开篇~~ n =10 #控制菱形的大小 for i in range(1, n): for j in range(int ...

  3. C++实现 企业信息管理系统

    2.1总体需求 ​ 2.2管理需求 ​ ​ 3.总体架构 ​ 由于代码量比较大,请移步GitHub或码云 码云:传送门 , GitHub:传送门 话不多说,直接上效果 我是在Linux Ubuntu1 ...

  4. 【题解】Luogu P5342 [TJOI2019]甲苯先生的线段树

    原题传送门 挺有趣的一道题 \(c=1\),暴力求出点权和n即可 \(c=2\),先像\(c=1\)一样暴力求出点权和n,考虑有多少路径点权和也为n 考虑设x为路径的转折点,\(L\)为\(x\)向左 ...

  5. golang基础学习---log

    package main import ( "log" ) func init() { log.SetPrefix("TRACE: ") log.SetFlag ...

  6. 运行一个docker镜像并开机启动

    记录,我用的liunx机是centos7.x 安装 安装Docker包$ sudo yum install docker-engine 启动Docker守护进程$ sudo service docke ...

  7. netcore访问本地磁盘

    public void ConfigureServices(IServiceCollection services) { services.AddDirectoryBrowser(); }public ...

  8. modbus协议使用小记

    下载了libmodbus库,交叉编译后运行,总是接收回复时不正确.原因不明. 由于使用到modbus的需求比较简单,所以选择直接拼出modbus的请求报文,然后用串口直接发送和接收的方式, 拼modb ...

  9. AS shortcuts

    stl => statelessstf => statefulalt+enter, select element => add pading or somethingselect c ...

  10. 使用jmeter对dubbo接口进行性能测试教程及常见问题处理

    一.   测试脚本编写 脚本可参考git项目: https://github.com/aland-1415/dubbo-interface-test.git 1. pom依赖 (注意添加的jmeter ...