前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

Promise

作者头像
云台大树
修改2021-07-30 17:02:18
6710
修改2021-07-30 17:02:18
举报

Promise

Promise对象用于呈现异步操作事件的完成/失败结果。 此篇文章翻译自Promise,原文章太长,因此自己在这里做了简化,以便自己加强认识和理解。 实际上Promise的用法非常简单,自己不太理解的只是then() finally() catch()在链式调用时缺省回调函数的情况

Description

Promise像某个值的代理,该值在promise实例被创建时并不需要知道。它把某个异步行为的成功结果或失败原因关联到某个响应器(handler)。它使得异步方法像同步方法一样返回值:但它并不完全像同步方法一样直接返回值,而是通过返回一个promise实例,在未来的某个时候呈现返回值。

Promisepromise不是一个概念。大写的代表某个类,小写的表示某个具体的实例

Promise总是在以下3种状态中变动:

  • pending 初始状态
  • fulfilled 表示某项操作(方法)成功
  • rejected 表示某项操作失败

一个处于pending状态的promise实例,要么被fulfilled with a value,要么rejected with a reason(error)。上述两种情况发生时候,通过promise的then()方法关联的响应器

promise states
promise states

链式Promises

当一个promise处于settled状态时,promise.then() promise.catch() promise.finally() 视情况被调用

settled状态即fulfilledrejected

then()方法有两个参数:

  • 第一个参数是一个回调函数,用于promise被满足时(resolved/fulfill)
  • 第二个参数是一个回调函数,用于promise被拒绝时(rejrected/reject)

注意该方法返回一个新生成的promise对象,它的状态是pending

需要特别说明的是:当then()缺少一个回调函数时,链式调用不会被影响,将会继续执行下一个动作(上一个then()的返回值作为下一个then()的入参)。这就是说在链式调用中可以不需要设置rejection callback function,链式调用中的reject动作可以被catch()方法捕捉。

下面用代码说明上述的内容

const myPromise = new Promise((resolve, reject) => {
    setTimeout(()=> {
        resolve('foo');
    }, 500);
});
myPromise.then( value => { 
    console.log(value); // print 'foo'
    return 'hello'; 
}).then( value => { 
    console.log(value); // print 'hello'
    return 'world';
}).then( value => { 
    console.log(value); // print 'world'
    throw 'error!!!'; 
}).catch( value => { 
    console.log(value); // print 'error!!!' 
});

常用方法

  • Promise()

该构造函数返回一个状态为pendingpromise对象,这个构造方法的最大作用是包装一个方法,使其能支持promise。该构造函数有一个executor参数,该参数是一个回调函数。该回调参数有两个入参resolve reject,这两个入参函数的调用将改变产生的promise的状态 - fulfilled / rejected

function myAsynchFunc(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        // 定义请求成功时的回调函数,该函数执行resolve动作
        xhr.onload = () => resolve(xhr.responseText);
        // 定义请求失败时的回调函数,该函数执行reject动作
        xhr.onerror = () => reject(xhr.statusText);
        xhr.send();
    });
}

Promise.resolve(value)Promise.reject(reason)都将直接创建一个settledpromise对象

下面的三个方法都会返回一个新的promise对象,用法比较简单,前面说过了,不细说了

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

还有4个比较特殊的静态方法 - 用于promise对象组上的操作

  • Promise.all(iterable)

等待可迭代对象中的promise对象都被resolvedrejected

如果全部都是resolved,则它的resolve handler的入参是一个数组,该数组的值是所有promise对象的resolve时的返回值;

如果有一个rejected了,那其rejected handler的入参是第一个rejectedpromise对象的reject时的返回值

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
  console.log(values);
}, reason => {console.log(reason)});
// expected output: Array [3, 42, "foo"]
  • Promise.allSettled(iterable)

Promise.all(iterable)类似,等待所有的promise对象都被settled,但其入参是一个数组,数组中包含所有promise对象的执行结果(不区分对待fulfilledrejected

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

// results入参是一个数组
Promise.allSettled(promises).then((results) => results.forEach((result) => console.log(result.status)));
  • Promise.race(iterable)

只要其中任一一个promise对象状态settlled,则该方法产生的promise对象的状态也立马settled。 如果第一个settledpromise对象是resolved,则该方法产生的promise也立马resolved,且值和所述的第一个promise对象一样。如果第一个是rejected,同理!

  • Promise.any(iterable)

只要其中任一一个promise对象状态fulfilled,则该方法产生的promise对象的状态也立马resolved

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Promise
  • Description
  • 链式Promises
  • 常用方法
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档