js基本功(八)
Promise
情况一
const promise = new Promise(function(resolve, reject) {
if (1 === true){
resolve('success');
} else {
reject('fail');
}
});
promise.then(function(value) {
console.log(value)
}, function(error) {// reject作为then的第二个参数
console.log(error)
});
promise.then(function(value) {
console.log(value)
}).catch( function(error) { // reject在catch里面
console.log(error)
});
情况二
resolve, reject不会阻塞后面代码的执行
new Promise((resolve, reject) => {
resolve(1);
console.log(2);// 有执行这行代码
})
new Promise((resolve, reject) => {
reject(1);
console.log(2);// 有执行这行代码
})
new Promise((resolve, reject) => {
return resolve(1);
// 后面的语句不会执行,因为有return
console.log(2);
})
Promise.resolve
情况一
Promise.resolve('foo').then((data) => {
console.log('resolve结果:', data)// resolve结果: foo
})
Promise.resolve({name: 'malinshu'}).then((data) => {
console.log('resolve结果:', data) // resolve结果: {name: 'malinshu'}
})
情况二
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))
情况三
const obj = {
then: function(resolve, reject) {
reject(42);
}
}
Promise.resolve(obj).then(function (value) {
console.log(value); //这里不执行,因为obj有then方法,then里面执行了reject,如果then里面执行了resolve就有执行这行代码,这就是resolve(obj)里有then的特殊性,但是obj里有catch就没有这种效果
}).catch( err => {
console.log('失败了:', err)// 执行了这行代码
});
情况四
const p1 = new Promise(() => {})
Promise.resolve(p1).then(() => {console.log('执行了resolve')}).catch(() => {console.log('执行了catch')})// 什么都没有打印,因为没有执行p1中没有执行resolve,reject
Promise.reject
const p = Promise.reject('出错了');
p.then(null, function (s) {
console.log(s)
});
Promise.all
从上面的例子可看出,当某个promise有自己的catch时,如果这个catch执行了,就不会执行all.catch
Promise.all结合async,await
情况一
const testPro = async () => {
const pro1 = new Promise()
const pro2 = new Promise()
await Promise.all([pro1, pro2])
console.log('执行console.log')//这行代码没执行
}
testPro()
情况二
const testPro = async () => {
const pro1 = new Promise(() => {})
const pro2 = new Promise(() => {})
await Promise.all([pro1, pro2])
console.log('执行console.log')//这行代码没执行
}
testPro()
情况三
const testPro = async () => {
const pro1 = new Promise((resolve) => {resolve()})
const pro2 = new Promise(() => {})
await Promise.all([pro1, pro2])
console.log('执行console.log')//这行代码没执行
}
testPro()
情况四
const testPro = async () => {
const pro1 = new Promise((resolve) => {resolve()})
const pro2 = new Promise((resolve) => {resolve()})
await Promise.all([pro1, pro2])
console.log('执行console.log')//执行了
}
testPro()
情况五
const testPro = async () => {
const pro1 = new Promise((resolve) => {resolve()})
const pro2 = new Promise((resolve,reject) => {reject()})
await Promise.all([pro1, pro2])
console.log('执行console.log')// 这行代码没执行
}
testPro()
const testPro = async () => {
try{
const pro1 = new Promise((resolve) => {resolve()})
const pro2 = new Promise((resolve,reject) => {reject()})
await Promise.all([pro1, pro2])
console.log('执行console.log1')
}catch{
console.log('执行console.log2')//执行了
}
testPro()
特别注意
const testPro = async () => {
const pro1 = new Promise((resolve,reject) => {reject()})
console.log('执行console.log')//执行了,即使是reject也执行这行代码,那promise.all也想要这样行不行,可以,用Promise.allSettled,如下
}
testPro()
Promise.allSettled
const testPro = async () => {
const pro1 = new Promise((resolve) => {resolve()})
const pro2 = new Promise((resolve,reject) => {reject()})
await Promise.allSettled([pro1, pro2])
console.log('执行console.log')// 这行代码执行了
}
testPro()
总结:只有promise.all的结果为resolve时,才会执行后面的代码
pending的概念
pending是一种状态,一旦 Promise 被创建,它默认处于 pending 状态。在这个状态下,Promise 的结果既不是成功(fulfilled),也不是失败(rejected)。
setTimeout
setTimeout可以传多个参数
function greet(...rest) {
console.log(rest);
}
setTimeout(greet, 2000, "Alice", 30);// ['Alice', 30]
Promise.all的面试题
当面试官问你,怎么兼容没有Promise.all的情况是,你可以这样回答(手写promise.all,也就是promise.all的polyfill):
if (!Promise.all) {
Promise.all = function(promises) {
// 返回一个新的 Promise
return new Promise((resolve, reject) => {
// 如果输入不是一个可迭代对象,直接抛出错误
if (!Array.isArray(promises)) {
throw new TypeError('Promise.all requires an iterable as input');
}
// 如果输入的数组为空,直接解析为一个空数组
if (promises.length === 0) {
resolve([]);
return;
}
// 用于存储每个 Promise 的解析结果
let results = [];
// 用于记录已经解析的 Promise 数量
let count = 0;
// 遍历输入的 Promise 数组
promises.forEach((promise, index) => {
// 确保每个元素都是 Promise(如果不是,将其包装为 Promise)
Promise.resolve(promise)
.then((value) => {
// 将解析结果存储到对应的位置
results[index] = value;
// 增加已解析的 Promise 数量
count++;
// 如果所有 Promise 都已解析,解析返回的 Promise
if (count === promises.length) {
resolve(results);
}
})
.catch((reason) => {
// 如果任何一个 Promise 被拒绝,立即拒绝返回的 Promise
reject(reason);
});
});
});
};
}
如果看不懂这段代码,可以先理解上面的Promise.all和Promise.resolve的情况四