一. Promise 是什么
为异步问题提供同步化的解决方案(解决回调地狱)
Promise 的三种状态
- pending:等待状态。如,正在进行网络请求,或定时器未到时间
- fulfilled(resolved):满足状态。如,当我们主动回调了 resolve 时,就处于该状态,且接下来会回调 .then()
- rejected: 拒绝状态。如,当我们主动回调了 reject 时,就处于该状态,且接下来会回调 .catch()(如果有catch)
Promise 的常规写法
<!--常规写法-->
new Promise((resolve, reject) => {
setTimeout(() => {
// -----1.响应成功时
// resolve('响应成功时,调用 resolve')
// -----2.响应失败时
reject('响应失败时,调用 reject')
}, 1000)
}).then(success => {
console.log(success); // 响应成功时,调用 resolve
}).catch(error => {
console.log(error); // 响应失败时,调用 reject
})
<!--其他写法-->
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
// reject('error')
}, 1000)
}).then(success => {
console.log(success); // 响应成功时,调用 resolve
}, error => {
console.log(error); // 响应失败时,调用 reject
})
二. Promise.resolve() 和 Promise.reject()
1. Promise.resolve()
Promise 的语法糖,更简易的将参数创建为一个 Promise 对象
- 当参数不带有 then 方法,则返回一个新的 Promise 对象,且其状态为 resolved
<!--Promise.resolve('erxun') 等价于 new Promise(resolve => resolve('erxun'))-->
const aa = Promise.resolve("erxun");
aa.then(res => {
console.log('aa~~~'+res) // aa~~~erxun
})
const bb = new Promise(resolve => resolve('erxun'))
bb.then(res => {
console.log('bb~~~'+res) // bb~~~erxun
})
- 当参数本身为 Promise 实例时,则直接返回此实例
const t = Promise.resolve('erxun')
console.log(Promise.resolve(t) === t); // true
- 参数是一个 thenable 对象(对象内具有 then 方法),则返回 Promise 实例的状态取决于 thenable 对象内的状态
<!-
1. thenable 对象内的状态为 resolved,则 实例 p 的 状态为 resolved
-->
const thenable = {
then: (resolve, reject) => {
resolve("resolve-thenable");
}
};
const p = Promise.resolve(thenable);
p.then(
(res) => {
console.log("resolved---" + res); // resolved---resolve-thenable
},
(err) => {
console.log("rejected---" + err); // 不执行
}
);
<!-
2. thenable 对象内的状态为 rejected ,则 实例 p 的 状态为 rejected
-->
const thenable = {
then: (resolve, reject) => {
reject("reject-thenable");
}
};
const p = Promise.resolve(thenable);
p.then(
(res) => {
console.log("resolved---" + res); // 不执行
},
(err) => {
console.log("rejected---" + err); // rejected---resolve-thenable
}
);
2.Promise.reject()
Promise.reject(rejectedInfo) 返回一个带有拒绝原因且状态为 rejected 的 Promise 对象
// from mdn
function resolved(result) {
console.log('Resolved');
}
function rejected(result) {
console.error(result);
}
Promise.reject(new Error('fail')).then(resolved, rejected);
// expected output: Error: fail
三. Promise.all() 和 Promise.any()
1. Promise.all() 可对多个 Promise 实例进行包装(包装成 iterable 类型),返回一个新的 Promise 实例 。
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('erxun')
}, 5000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve(18)
}, 1000)
})
]).then(res => {
console.log(res); // ["erxun", 18]
}, error => {
console.log(error);
})
- success:当所有 Promise 实例的 resolve 都回调结束,则按 Promise 实例的顺序(空间顺序)返回一个包含 所有resolve 结果的数组
- error:当有一个 promise 是 rejected ,则回调 reject 并且 reject 第一个抛出的错误信息
iterable 内部传递的不是 promise,则直接 resolve()
const p = Promise.all([1, true, "000"]);
p.then((res) => {
console.log(res); // [1, true, "000"]
});
iterable 内部传递的是空数组,则返回空数组
const p = Promise.all([]);
p.then((res) => {
console.log(res); // []
});
2. Promise.any()
- 只要有一个 promise 成功,就返回那个成功的 Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, "成功");
});
const p2 = Promise.resolve("erxun");
const p3 = Promise.reject("失败");
Promise.any([p3, p2, p1]).then(
(res) => {
console.log("resolve---" + res); // resolve---erxun
},
(error) => {
console.log("reject-----" + error); // 不执行
}
);
- 如果所有的 Promise 都失败,,就返回一个失败的 promise 和AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起(???)
const p1 = new Promise((resolve, reject) => {
setTimeout(reject, 500, "成功");
});
const p2 = Promise.reject("erxun");
const p3 = Promise.reject("失败");
Promise.any([p3, p2, p1]).then(
(res) => {
console.log("resolve---" + res); // 不执行
},
(error) => {
console.log("reject-----" + error); // reject-----AggregateError: All promises were rejected
}
);
四. Promise.race(),返回一个 Promise 对象
假设有 Promise.race([p1,p2,p3]), iterable 中 p1,p2,p3 谁的结果先返回,就返回那个结果,不论结果 resolve 或 reject
// from mdn
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 更快,所以它失败了
});