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+规范