概念
[Promise](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise)
是一个对象,它代表了一个异步操作的最终完成或者失败。本质上Promise是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了(这就有别于原来的ajax请求了)。
示例如下:
// 成功的回调函数
function successCallback(result) {
console.log("音频文件创建成功: " + result);
}
// 失败的回调函数
function failureCallback(error) {
console.log("音频文件创建失败: " + error);
}
createAudioFileAsync(audioSettings, successCallback, failureCallback)
更现代的函数会返回一个 promise 对象,使得你可以将你的回调函数绑定在该 promise 上。
如下:
const promise = createAudioFileAsync(audioSettings){
return new Promise((resolve, reject) => {
//resolve(someValue); // fulfilled
// 或
//reject("failure reason"); // rejected
})
};
promise.then(successCallback, failureCallback);
//或是
promise.then(success=>{}).catch(failure=>{})
链式调用
连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,开始下一个的操作,并带着上一步操作所返回的结果。在过去,要想做多重的异步操作,会导致经典的回调地狱:
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
现在,我们可以把回调绑定到返回的 Promise 上,形成一个 Promise 链:
doSomething().then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {
return doThirdThing(newResult);
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
then里的参数是可选的,catch(failureCallback)
是 then(null, failureCallback)
的缩略形式
prmoise.all
Promise.all() 方法接受一个可迭代的对象(Array,Map,Set),返回一个Promise实例。
一句话:Promise.all 等待所有都完成,或第一个失败
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);
});
// Array [3, 42, "foo"]
当传入的异步请求全部完成时返回 返回一个完成的promise。
当传入的异步请求有一个reject了,或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。并且不会再管其它 promise 是否完成
所以,当我们有多个异步请求,且在业务逻辑上他们有一定相关性就可以用promise.all()来统一请求
Promise.allSettled
Promise.all() 方法接受一个可迭代的对象(Array,Map,Set),返回一个Promise实例。
当多个彼此不依赖的异步任务时,或者是想知道每个promise的结果时,通常使用它。这就是他与 Promise.all的最大区别,不管传入的异步请求是不是全部都成功了,都会返回每一个的请求结果。而peomise.all遇到错误就会直接返回错误
对于每个结果对象,都有一个 status 字符串。如果它的值为 fulfilled,则结果对象上存在一个 value 。如果值为 rejected,则存在一个 reason ,如下:
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject('错误了'), 100));
const promises = [promise1, promise2];
Promise.allSettled(promises).then((results) => console.log(results))
//{status: 'fulfilled', value: 3}
//{status: 'rejected', reason: '错误了'}
Promise.race()
方法接受一个可迭代的对象(Array,Map,Set),返回一个Promise实例。
一旦迭代器中的某个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.any
Promise.any() 接收一个可迭代对象(Array,Map,Set),只要其中的一个 promise 成功,就返回那个已经成功的 promise。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise。如下例子:
const pErr = new Promise((resolve, reject) => {
reject("总是失败");
});
const pSlow = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "最终完成");
});
const pFast = new Promise((resolve, reject) => {
setTimeout(resolve, 100, "很快完成");
});
Promise.any([pErr, pSlow, pFast]).then((value) => {
console.log(value);
})
//很快完成
promise.any 与 promise.all的区别就在于:all是要全部都是resolve了 才会返回一个resolve。这个是其中任何一个resolve就返回resolve。
promise.any 与 promise.race的区别就在于:race是用第一个返回的promise来返回,不论是resolve还reject。any是用第一个成功状态的 promise 来返回
参考
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises 本文基本是这篇文章的学习笔记