Promise 对象本质上表示的是一系列操作的中间状态,或者说是未来某时刻一个操作完成或失败后返回的结果。 Promise并不保证操作在何时完成并返回结果,但是保证在当前操作成功后执行你对操作结果的处理代码,或在操作失败后,优雅地处理操作失败的情况。 ——-MDN
Promise是什么?
根据开发者工具打印出来就知道
由此可见,Promise是JS一个内置对象了。
Promise 的用途
- Promise是目前前端解决异步问题的统一方案,为异步操作提供统一接口。
- 与之进行交互的方式主要是
then方法,该方法注册了两个回调函数,用于接收 promise 的终值或本 promise 不能执行的原因。 - Promise 用于避免回调地域,让代码看起来更同步。
如何创建一个 new Promise
promise对象是由关键字new及其构造函数来创建的。- 该函数构造会把一个叫做“处理器函数”(executor function)的函数作为它的参数。
- 这个“处理器函数”接受两个函数 ——
resolve和reject—— 作为其参数。 - 当异步任务顺利完成且返回结果值时,会调用
resolve函数; 而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用
reject函数。const promise = new Promise((resolve, reject) => {if(/*异步操作成功*/){resolve(value)} else {reject(error)}});
如何使用 Promise.prototype.then
then()方法返回一个Promise。- 它最多需要有两个参数:Promise 的成功和失败情况的回调函数。
语法:
Promise.prototype.then((value) => {// Promise状态变为成功时回调的函数}, (reason) => {// Promise状态变为失败时回调的函数})
以上面的“如何创建一个new promise”的代码作为使用方法:
promise.then((Message) => {//Message的值是上面调用resolve(...)方法传入的值.//Message参数不一定非要是字符串类型console.log("成功" + Message);},(Message) => {console.log("成功" + Message);});
完成使用例子:
function timeout(ms){return new Promise((resolve, reject) => {setTimeout(resolve, ms, 'done');});}timeout(100).then((value) => {console.log(value)})
如何使用 Promise.all
**Promise.all(iterable)**方法返回一个Promise实例- 此实例在
iterable参数内所有的promise都“完成(resolved)”或参数中不包含promise时回调完成(resolve) - 如果参数中
promise有一个失败(rejected),此实例回调失败(reject),失败的原因是第一个失败promise的结果。
语法:
Promise.all(iterable);//iterable是一个可迭代对象,如 Array 或 String。
作用:此方法在集合多个 promise 的返回结果时很有用。
使用:
let p1 = Promise.resolve(3);let p2 = 1337;let p3 = new Promise((resolve, reject) => {setTimeout(resolve, 100, 'foo');})Promise.all([p1,p2,p3]).then(values => {console.log(values);//[3, 1337, "foo"]})
即使参数里面包含非 promise 值,这些值将被忽略,但依然被放在返回数组中:
var p = Promise.all([1,2,3]);var p2 = Promise.all([1,2,3, Promise.resolve(444)]);var p3 = Promise.all([1,2,3, Promise.reject(555)]);setTimeout(() => {console.log(p);console.log(p2);console.log(p3);});// logs// Promise { <state>: "fulfilled", <value>: Array[3] }// Promise { <state>: "fulfilled", <value>: Array[4] }// Promise { <state>: "rejected", <reason>: 555 }
如何使用 Promise.race
**Promise.race(iterable)** 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。
var p1 = new Promise(function(resolve, reject) {setTimeout(resolve, 500, "one");});var p2 = new Promise(function(resolve, reject) {setTimeout(resolve, 100, "two");});Promise.race([p1, p2]).then(function(value) {console.log(value); // "two"// 两个都完成,但 p2 更快});
var p3 = new Promise(function(resolve, reject) {setTimeout(resolve, 100, "three");});var p4 = new Promise(function(resolve, reject) {setTimeout(reject, 500, "four");});Promise.race([p3, p4]).then(function(value) {console.log(value); // "three"// p3 更快,所以它完成了}, function(reason) {// 未被调用});
var p5 = new Promise(function(resolve, reject) {setTimeout(resolve, 500, "five");});var p6 = new Promise(function(resolve, reject) {setTimeout(reject, 100, "six");});Promise.race([p5, p6]).then(function(value) {// 未被调用}, function(reason) {console.log(reason); // "six"// p6 更快,所以它失败了});
如何使用Promise.prototype.catch()
例子:
timeout(100).then((value) => {console.log(value)}).catch((error)=>{console.log('发生错误!', error);})//写法与下面相同作用timeout(100).then((value) => {console.log(value)}, ((err) => {console.log(err)})
上面代码中,timeout(100) 会返回一个 Promise 对象,如果该对象状态变为 resolved, 则会调用 then()方法指定的回调函数;反之,如果异步操作抛出错误,状态就会变成 rejected ,就会调用 catch() 方法制定的回调函数。或是运行中发生错误,catch()会捕获该错误。
建议使用第一种写法,因为第一种写法可以捕获前面then() 方法执行中的错误,前面有多少个then(),也就除了多少个错误,同时更接近同步的写法(try/catch)。因此建议使用第一种写法。而不是then的第二个参数.
Promise.protoytpe.finally()
finally()方法用于不管 Promise对象最后状态如何,都会执行的操作。
promise.then(result => {...}).catch(error => {...}).finally(() => {...}) //不管前面代码如何,最后这一行都会执行!
【资料来源】 MDN Promise JavaScript Promise:简介 优雅的异步处理 【翻译】Promises/A+规范
