3个实例方法
Promise.prototype.then()
js
const promise1 = new Promise((resolve, reject) => {
resolve('Success!');
});
promise1.then((value) => {
console.log(value);
// Expected output: "Success!"
});
Promise.prototype.catch()
js
const promise1 = new Promise((resolve, reject) => {
throw new Error('Uh-oh!');
});
promise1.catch((error) => {
console.error(error);
});
// Expected output: Error: Uh-oh!
Promise.prototype.finally()
js
function checkMail() {
return new Promise((resolve, reject) => {
if (Math.random() > 0.5) {
resolve('Mail has arrived');
} else {
reject(new Error('Failed to arrive'));
}
});
}
checkMail()
.then((mail) => {
console.log(mail);
})
.catch((err) => {
console.error(err);
})
.finally(() => {
console.log('Experiment completed');
});
6个静态方法
Promise.all()
js
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);
});
// Expected output: Array [3, 42, "foo"]
Promise.allSettled()
js
const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];
Promise.allSettled(promises).then((results) => results.forEach((result) => console.log(result.status)));
// Expected output:
// "fulfilled"
// "rejected"
Promise.any()
js
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const promises = [promise1, promise2, promise3];
Promise.any(promises).then((value) => console.log(value));
// Expected output: "quick"
Promise.race()
js
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then((value) => {
console.log(value);
// Both resolve, but promise2 is faster
});
// Expected output: "two"
Promise.reject()
js
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.resolve()
js
const promise1 = Promise.resolve(123);
promise1.then((value) => {
console.log(value);
// Expected output: 123
});
Promise穿透
"Promise穿透"是指在Promise链中,如果在then或catch的处理函数中返回的不是一个新的Promise,那么下一个then或catch会接收到上一个then或catch返回的值
js
Promise.resolve(1) .then(() => {
// 这里没有返回新的Promise,也没有返回值,所以状态会被穿透到下一个then
}) .then(value => {
// 输出undefined,因为状态被穿透了
console.log(value)
})
js
var myselflog=function(a){
console.log("myselflog:"+a);
}
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(myselflog);
// 输出myselflog:1
手动实现allSettled
allSettled是最近才有的,为了兼容性有时需要自定义实现
js
// allSettled是即使错误了也都返回一步的promise
// 思路是让 Promise.all 入参中的所有 promise 都映射为新的最终状态为 fulfilled 的 promise
// 也可以通过逐个遍历的方式实现
Promise.allSettled = function (promises) {
return Promise.all(
promises.map((p) =>
Promise.resolve(p).then(
(res) => {
return {
status: 'fulfilled',
value: res
}
},
(error) => {
return {
status: 'rejected',
reason: error
}
}
)
)
)
}
终止Promise向下执行
js
Promise.resolve()
.then(() => {
console.log('Step 1');
return new Promise(() => {});
})
.then(() => {
console.log('Step 2');
// 这里不会被执行
})
在这个例子中,第一个then方法中返回了一个新的Promise,这个Promise永远不会被resolve或reject,所以第二个then方法不会被执行。 然而,这种方法并不是真正意义上的"终止"Promise,因为新的Promise仍然在运行,只是它永远不会被settled,所以后续的then方法不会被执行。这可能会导致内存泄漏等问题,所以在实际开发中需要谨慎使用。
Sleep函数
js
const wait = (ms) => new Promise((resolve)=> setTimeout(resolve, ms))
const asyncFn = async () => {
await wait(1000)
console.log('等待异步函数执行结束')
}
asyncFn()
Promise串行
js
class PromiseChunk {
constructor () {
this.maxCount = 3
this.curCount = 0
this.parr = []
}
addPromise (p) {
this.parr.push(p)
}
start () {
for (let i = 0; i < this.maxCount; i++) {
this.executePromise(this.parr[i])
}
}
executePromise () {
if (this.curCount >= this.maxCount || this.parr.length === 0) {
return false
}
this.curCount++
const p = this.parr.shift()
p.then((res) => {
console.log(res, '33333333')
this.curCount--
this.executePromise()
})
}
}
const pc = new PromiseChunk()
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 3000)
})
pc.addPromise(p1)
pc.addPromise(p2)
pc.addPromise(p3)
pc.start()
Promise并行
可以直接使用Promise.all()实现
js
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);
});
// Expected output: Array [3, 42, "foo"]
myPromise
从一道让我失眠的 Promise 面试题开始,深入分析 Promise 实现细节