11、异步操作之Promise—ES6学习笔记

Promise

基本概念
- promise:是ES6中新增的异步编程解决方案,体现在代码中它是一个对象,可以通过 Promise构造函数来实例化。

  • new Promise(cb) ===>实例的基本使用 Pending Resolved Rejected

    两个原型方法

    • Promise.prototype.then()
    • Promise.prototype.catch()

    两个常用的静态方法

    • Promise.all()
    • Promise.resolve()

首先我们来解释一下什么是异步?
打个比方,你想买一套房子,这个时候你需要去售楼处咨询一下,所以你就给售楼处打了一个电话,于是就有一个大叔接了你的电话,然后就问你:
“小伙子,你想买什么样的房子啊?”
,然后你就说
“要什么什么样的”,
这个时候大叔就需要去看看有没有符合你说的要求的房子,大叔就会和你说:
“小伙子你等一下,我帮你查一下”
,这个时候你在电话里等啊等,不一会大叔回来告诉你,
“查了,你说的这个房子的类型没有了”,
然后挂了电话。

这个过程中,打电话的时候,一直在等待对方的结果,这个时候其实就是一个同步的过程,那么相反的就是异步,异步就好比你打了一个电弧,不是一个大叔接的,而是一个售楼小妹接的,这个小妹就和你说,先生你稍等一下,你可以先挂了电话,我去查一下,如果查好了我在打你的电话给你回复你,然后告诉你结果。

这是打电话之后你可以挂了,挂了之后该干嘛干嘛去,然后等她的结果就可以了,这个时候可能小妹查好了,给你回了个电话告诉你结果,就OK了。这个过程就是异步的。

那么Promise对象,就是处理异步过程的一个对象
既然学习Promise呢,我们主要通过三个方面去学习它。
首先是它的构造函数new Promise(cb),然后是构造函数原型上的方法,已经构造函数本身的两个静态方法。

那么我们先来看看Promise对象

// new Promise(cb)
// Pending(进行中) ===> Resolved(已完成)
// Pending(进行中) ===> Rejected(已失败)

一个Promise对象它的状态完全取决于它的异步操作的结果来决定的,如果说这个异步操作成功了,那正在进行当中的时候就是Pending,如果已经成功了就会变成Resolved(已完成),如果失败了就会变成Rejected(已失败)。
同时这个Promise对象它的状态一旦改变之后,就不能再变了。也就是说成功了就是成功,失败了也不可能再变成功。
那这是怎么回事呢,我们演示一下,我们准备一个数组,里面有一堆地址

接下来,我们实例化一个对象,这个对象当中,可以接收一个参数
resolve代表异步操作执行成功的回调函数,reject代表异步操作失败时候的回调函数。
这里我们以图片加载为例子来说:

const p = new Promise(function(resolve,reject){
    const img = new Image();
    img.src = imgs[0];
    img.onload = function(){
        resolve(this); //当图片加载成功的时候就执行resolve
    };
    img.onerror = function(err){
        reject(err);//当图片加载失败的时候我们就返回失败的信息
    }
});

这个时候我们就创建完成的了Promise对象,这个时候运行一下什么都没有,控制台也没有什么信息,那么怎么知道它完成了呢?这个时候就需要Promise对象原型上的两个方法了。

两个原型方法
- Promise.prototype.then()
- Promise.prototype.catch()

这里面一旦完成就可以调用then了,如下

//这里面可以接收两个参数,第一个参数是一个函数,就是resolve;第二个参数也是一个函数,就是reject
//同时函数里面参数,我们就可以指定了,这么这里面通过onload执行成功传了一个参数
//我们做一个简单的操作,把图片添加到body当中
console.log(123);
p.then(function(img){
    console.log("加载完成");
    document.body.appendChild(img);//这个时候保存一下,可以发现一张图片就被加载到页面中了,而且过程全部是异步的
})
console.log(456);


我们发现首先显示的是123,然后显示456,最后显示“加载完成”,这个就说明了 Promise实际上是一个异步的操作。它并不会影响后面的代码执行。

.then()是promise原型上的一个方法,它是promise异步操作,执行之后要调用的一个函数,它能调用两个回调函数,一个是执行成功的回调函数,另一个是执行失败的回调函数。
这时我们再把src设为空;它就打印出了报错信息。

一般情况下.then()当中不推荐写第二个参数捕获异常,而是使用原型当中的第二个方法.catch()来捕获异常。
这个时候依然显示报错信息.

以上就是Promise原型上的两个方法,一个叫.then()一个.catch()。分别是用来调用Promise异步结束之后结果的两个回调函数。

我们将这个函数封装一下

function loadImg(url){
 const p = new Promise(function(resolve,reject){
    const img = new Image();
    img.onload = function(){
        resolve(this);
    };
    img.onerror = function(){
        reject(new Error("图片加载失败 "));
    };
 });
 return p;
}

//调用
loadImg(img[0]).then(function(){
  document.body.appendChild(img)
})

接下来,我们来看看Promise.all

Promise.all 可以将多个Promise实例包装成一个新的Promise实例

  • 当所有的Promise实例的状态都变成resolved,Promise.all的状态才会变成resolved,此时返回值组成一个数组,传递给then中的resolve函数。

  • 只要其中一个被rejected,Promise.all的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

const allDone = Promise.all(loading(imgs[0]),loading(imgs[1]),loading(imgs[2]));

allDone.then(function(datas){
  console.log(datas);//[img,img,img]
  //我们可以使用forEach方法将图片加到页面当中
  datas.forEach(function(item,i){
    document.body.appendChild(item);
  });
})

可以发现三张图片同时被加载到页面当中

那么如果有个失败呢?

接下来,我们在来介绍一下Promise.resolve()
它主要是将其他对象转换成Promise对象

参数是Promise实例,将不做任何修改,原封不动地返回这个实例。

Promise.resolve(loadImg(imgs[0])).then(function(img){
    document.body.appendChild(img);
})

将对象是Promise实例,将不做任何修改,原封不动地返回这个实例。

Promise.resolve({
    then(resolve,reject){
        const img = new Image();
        img.src = imgs[1];
        img.onload = function(){
          resolve(this);
        }
    }
}).then(function (img){
    document.body.appendChild(img);
})

参数是一个基本数据类型或者不传参数,那么返回一个状态为 resolved的Promise对象

Promise.resolve('zhang').then(function(str){
    console.log(str);
})

const p = Promise.resolve();
console.log();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值