ES6 Promise

一、什么是 Promise

Promise 对象用于表示一个异步操作的最终状态(完成或失败)以及返回的值。

二、Promise 的状态

  • pending(进行中)
  • fulfilled(已成功)
  • rejected(已失败)

Promise 的状态只有两种可能,从 pending 变为 fulfilled 和 从 pending 变为 rejected,一旦状态变化,就不会再改变

三、手写一个 Promise

var promise = new Promise((resolve, reject) => {
    if (操作成功) {
        resolve(value)
    }
    else {
        reject(error)
    }
});

promise.then(function (value) {
    // success(接收resolve传来的数据,做些什么)
}, function (error) {
    // failure(接收reject传来的数据,做些什么)
});

其中,promise.then() 接收两个参数,resolved 状态的回调函数和 rejected 状态的回调函数

四、Promise.catch()

catch 方法是.then(null, rejection) 的别名,用于指定发生错误时的回调函数

promise.catch(function (error) {
    // failure(接收reject传来的数据或捕捉到then()中的运行报错时,做些什么)
});

五、Promise.finally()

finally 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作

promise.finally(function () {
    // 不管什么状态都执行此函数
});

六、Promise.all()

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

all 接收一个数组参数:

(1)只有 getData1、getData2、getData3、getData4 的状态都变成 fulfilled,Promise 的状态才会变成 fulfilled,此时 getData1、getData2、getData3、getData4 的返回值组成一个数组,传递给 Promise 的回调函数

function getData1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第一条数据加载成功');
            resolve('data1');
        }, 1000);
    });
}

function getData2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第二条数据加载成功');
            resolve('data2');
        }, 1000);
    });
}

function getData3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第三条数据加载成功');
            resolve('data3');
        }, 1000);
    });
}

function getData4() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第四条数据加载成功');
            resolve('data4');
        }, 2000);
    });
}

let p = Promise.all([ getData1(), getData2(), getData3(), getData4()]);

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


(2)只要 getData1、getData2、getData3、getData4 之中有一个被 rejected,Promise 的状态就变成 rejected,此时第一个被 reject 的实例的返回值,会传递给 Promise 的回调函数

function getData1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第一条数据加载成功');
            resolve('data1');
        }, 1000);
    });
}

function getData2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第二条数据加载成功');
            resolve('data2');
        }, 1000);
    });
}

function getData3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第三条数据加载成功');
            resolve('data3');
        }, 1000);
    });
}

function getData4() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            // console.log('第四条数据加载成功');
            reject('data4 err');
        }, 500);
    });
}

let p = Promise.all([ getData1(), getData2(), getData3(), getData4()]);

p.then(arr => {
    console.log(arr);
}, e => {
    console.log(e);
});


七、Promise.race()

race 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例

与 all 方法的区别是:Promise.race([p1, p2, p3]) 里面哪个结果获得的快,就返回哪个结果,不管结果本身是成功状态还是失败状态

function getData1() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第一条数据加载成功');
            reject('err');
        }, 500);
    });
}

function getData2() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第二条数据加载成功');
            resolve('data2');
        }, 1000);
    });
}

function getData3() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('第三条数据加载成功');
            resolve('data3');
        }, 1000);
    });
}

let p = Promise.race([ getData1(), getData2(), getData3() ]);

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


八、Promise.all() 和 Promise.race() 的应用

1、Promise.all()

// 所有图片加载完再添加到页面
function loadImg(src){
  return new Promise((resolve,reject)=>{
    let img=document.createElement('img');
    img.src=src;
    img.onload=function(){
      resolve(img);
    }
    img.onerror=function(err){
      reject(err);
    }
  })
}
function showImgs(imgs){
  imgs.forEach(function(img){
    document.body.appendChild(img);
  })
}
Promise.all([
  loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png'),
  loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),
  loadImg('http://i2.muimg.com/567751/5eb8190d6b2a1c9c.png')
]).then(showImgs)

2、Promise.race()

function loadImg(src){
  return new Promise((resolve,reject)=>{
    let img=document.createElement('img');
    img.src=src;
    img.onload=function(){
      resolve(img);
    }
    img.onerror=function(err){
      reject(err);
    }
  })
}
function showImgs(img){
  let p=document.createElement('p');
  p.appendChild(img);
  document.body.appendChild(p)
}
Promise.race([
  loadImg('http://i4.buimg.com/567571/df1ef0720bea6832.png'),
  loadImg('http://i4.buimg.com/567751/2b07ee25b08930ba.png'),
  loadImg('http://i2.muimg.com/567751/5eb8190d6b2a1c9c.png')
]).then(showImgs)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue过渡效果的实现

    Leophen
  • ES8 Async 和 Await

    Async 和 Awaiit 是 Promise 的扩展,我们知道 JavaScript 是单线程的,使用 Promise 之后可以使异步操作的书写更简洁,而 ...

    Leophen
  • 通过CDN引入jQuery的几种方式

    Leophen
  • 初识promise

    new Promise( function(resolve, reject) { } );

    wade
  • ES6笔记(7)-- Promise异步编程

    Promise是一种异步编程的解决方案,本质来说其实它是一种规范,Promises/A+规范

    书童小二
  • ES6系列_14之promise对象的简单使用

    在前端开发中,最常见的的就是"回调",我相信很多人对于这个"回调"可谓是印象深刻呢。究其原因是因为层层回调会造成所谓的“回调地狱 (callback hell)...

    wfaceboss
  • Promise杂记 前言APIPromise特点状态追随V8中的async await和Promise实现一个Promise参考

    作为一个前端开发,使用了Promise一年多了,一直以来都停留在API的调用阶段,没有很好的去深入。刚好最近阅读了V8团队的一篇如何实现更快的async awa...

    菜的黑人牙膏
  • 这一次,彻底弄懂 Promise 原理

    Promise 必须为以下三种状态之一:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。一旦Promise 被 resolv...

    winty
  • JavaScript之Promise对象

    Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,...

    laixiangran
  • Promise/async/Generator实现原理解析

    笔者刚接触async/await时,就被其暂停执行的特性吸引了,心想在没有原生API支持的情况下,await居然能挂起当前方法,实现暂停执行,我感到十分好奇。好...

    Nealyang

扫码关注云+社区

领取腾讯云代金券