什么是Promise?
⚠️笔者默认读到这篇文章的人有JavaScript基础运行原理的相关知识,如果对JavaScript运行原理不甚了解,可以先简单阅读下这篇文章「硬核JS」一次搞懂JS运行机制。后续笔者也会写一篇较为基础的JavaScript运行机制浅析。
在JavaScript执行的过程中,我们会遇到很多异步任务。因为这些任务不在主线程上进行,而是由相应的异步处理模块处理,我们为了能够获得这个异步任务的执行结果,往往会注册一个回调函数给异步任务,在异步任务完成时调用回调函数,将执行结果作为参数传回。
而Promise正是异步编程的一类通用解决方案。简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。 它最为称道的优点就是通过支持链式调用,解决繁冗的「回调地狱」问题。
如何使用Promise?
-
如何创建一个 new Promise
1 2 3 4 5
const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve('好耶,是大冒险时间!'); }, 300); });
创建一个实例化的
promise
对象非常简单,只需要使用new Promise
来进行构造。一般来说Promise
构造函数接收一个函数作为其参数,而该函数的两个参数分别是resolve
和reject
,当函数体内的异步操作成功执行就调用resovle
,失败就调用reject
。 -
如何使用 Promise.prototype.then
1 2 3 4 5 6 7 8 9 10 11
const myPromise = new Promise((resolve, reject) => { setTimeout(() => { resolve('好耶,是大冒险时间!'); }, 300); }); myPromise .then((value)=>{ console.log(value) }) //好耶,是大冒险时间!
实例方法
then()
返回一个promise
对象,它最多需要有两个参数:Promise 的成功和失败情况的回调函数。听起来有些绕口,实际上就是
myPromise.then( success , fail )
。如果还是觉得有些难以理解的话,那么这张图可能会为你解惑⬇️
◎ 试着运行myPromise与myPromise.then( ... )
myPromise
是一个promise
对象,fulfilled
代表了异步操作处于完成状态并调用了设定的resolve
函数,PromiseResult
为值(value)。到此为止,如果我们不补充then()
方法的话,我们并不能知道myPromise
的执行结果(诚然在简单情况下,比如图例中,你大可以自己打印一下整个对象,然后寻找需要的PromiseResult
),而补充了then(...)
方法作为回调函数,在输出端,我们可以直接获取到想要的值,同时它返回的也是一个promise
对象,可以供后续进行进一步的链式操作。 -
如何使用 Promise.all
1 2 3 4 5 6 7 8 9 10
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); }); // [3, 42, 'foo']
Promise.all()
方法可以一次性接收多个promise
对象,但是只会返回一个Promise
实例,不过存在两种返回情况:- 所传入的
promise
均正常执行并返回,resolve 的回调结果是一个数组,它包含所有的传入迭代参数对象的值(也包括非 promise 值)。 - 如果传入的
promise
中有一个失败(rejected),Promise.all
就会返回第一个失败的结果,不论其他promise
是否完成。
- 所传入的
-
如何使用 Promise.race
1 2 3 4 5 6 7 8 9 10 11 12
const promise1 = new Promise((resolve, reject) => { setTimeout(resolve, 500, '这个500就是又慢又逊啦'); }); const promise2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, '快人一步,懂?'); }); Promise.race([promise1, promise2]).then((value) => { console.log(value); }); // 快人一步,懂?
Promise.race()
方法可以一次性接收多个promise
对象,同样只会返回一个Promise
实例,不过这种返回「人如其名」,是一场「竞赛」:- 所传入的
promise
对象,只要有一个状态发生改变(不论成功resolve/失败reject),Promise.race()
会直接返回第一个完成的promise
。
- 所传入的