手写Promise
源码:
type State = "pending" | "resolved" | "rejected";
// 构造函数的回调
// new Promise(Executor)
// new Promise((resolve, reject) => {})
type Executor = (resolve: Function, reject: Function) => any;
// p.then(ThenCB, ThenCB)
type ThenCB = (res: any) => any;
// then 方法每执行一次,就会创建一个 Item
// 每一个item, 就对应一个异步任务, then的回调就在异步任务中执行
type Item = {
onResolved: ThenCB; // then的回调: .then(成功函数)
onRejected: ThenCB; // then的回调: .then(, 失败函数)
nextPromise: {
resolve: Function;
reject: Function;
};
};
export default class MyPromise {
_state: State;
_value: any;
items: Item[]; // 存储所有 then 方法的回调
constructor(executor: Executor) {
this._state = "pending";
this._value = undefined;
this.items = [];
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (err) {
this.reject(err);
}
}
// ------------------------------
// 核心:改变状态
// ------------------------------
// executor(this._resolve, this._reject)
// new Promise((resolve, reject) => {})
private resolve(value?: any) {
// 状态吸收只在resolve时发生, reject不发生
if (islikePromise(value)) {
pushToTaskQueue(() => value.then(this.resolve, this.reject));
return;
}
this.changeState("resolved", value);
}
// executor(this._resolve, this._reject)
// new Promise((resolve, reject) => {})
private reject(value?: any) {
this.changeState("rejected", value);
}
private changeState(state: State, value: any) {
// 状态更改后就不能变了
if (this._state !== "pending") {
return;
}
this._state = state;
this._value = value;
this.runAllItems();
}
// ------------------------------
// 执行 then 队列
// ------------------------------
/**
* 极简一句话总结:
* 执行 then 回调 → 没回调就透传 → 有回调就执行 → 返回值是 Promise 就跟着它,不是就直接成功
*
* 最精简专业版总结:
* 1.根据当前状态选择成功 / 失败回调
* 2.如果无回调则状态透传给下一个 Promise
* 3.如果有回调则执行并获取返回值 x
* 4.如果 x 为 Promise 则状态跟随,否则直接决议成功
*
* 谁在调用函数 task:
* pushToTaskQueue(() => task(item))
*/
task(item: Item) {
const value = this._value;
const { onResolved, onRejected, nextPromise } = item;
const state = this._state;
const thenCB = state === "resolved" ? onResolved : onRejected;
// 透传
if (!thenCB) {
state === "resolved"
? nextPromise.resolve(value)
: nextPromise.reject(value);
return;
}
const x = thenCB(value);
if (islikePromise(x)) {
pushToTaskQueue(() => x.then(nextPromise.resolve, nextPromise.reject));
return;
}
nextPromise.resolve(x);
}
/**
* 每一个 Item 都会产生一个异步任务
*
* 什么时候执行:
* 情况1: resolve, reject 执行时触发
* 情况2: then 方法执行时发现promise对象状态已经改变
* Promis.resolve().then(() => alert(1))
* 注意:
* 异步任务产生后记得将 item 从 list 中删除, 防止反复执行
* const p = Promise.resolve()
* p.then(() => {console.log(1)})
* p.then(() => {console.log(2)})
* then ---生---> item ---生--> 异步任务
*/
private runAllItems() {
if (this._state === "pending") {
return;
}
while (this.items.length) {
const item = this.items.shift();
pushToTaskQueue(() => {
try {
this.task(item);
} catch (error) {
item.nextPromise.reject(error);
}
});
}
}
// 谁在调用函数 addItem: then 方法
addItem(
onResolved: ThenCB,
onRejected: ThenCB,
nextPromise: Item["nextPromise"],
) {
this.items.push({
onResolved,
onRejected,
nextPromise,
});
}
// ------------------------------
// 实例方法
// ------------------------------
then(onResolved?: ThenCB, onRejected?: ThenCB) {
return new MyPromise((resolve, reject) => {
const nextPromise = { resolve, reject };
this.addItem(onResolved, onRejected, nextPromise);
// 如果promise的状态已经确定, 就立即执行异步任务
if (this._state !== "pending") this.runAllItems();
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(callback: Function) {
return this.then(
(res) => {
callback();
return res;
},
(err) => {
callback();
throw err;
},
);
}
// ------------------------------
// 静态方法
// ------------------------------
// 状态吸收
// const p = Promise.reject("我失败了")
//
// Promise.resolve(p).catch(err => {
// console.log(err) // 👈 输出:我失败了
// })
static resolve(value?: any) {
if (islikePromise(value)) {
return value;
}
return new MyPromise((resolve) => resolve(value));
}
// const p = Promise.resolve("我成功了")
//
// Promise.reject(p).catch(err => {
// console.log(err) // 👈 输出:整个 p 对象!
// })
static reject(reason?: any) {
return new MyPromise((_, reject) => reject(reason));
}
static all(promises: MyPromise[]) {
return new MyPromise((resolve, reject) => {
const values = [];
let count = 0;
const add = (i, v) => {
values[i] = v;
count++;
if (count >= promises.length) resolve(values);
};
promises.forEach((p, i) => {
MyPromise.resolve(p).then(
(res) => add(i, res),
(rej) => reject(rej),
);
// 其实可以写成下面这样, 但p就必须是promise对象,不然会出错
// p.then(
// res => add(i, res),
// rej => reject(rej)
// )
});
});
}
static race(promises: MyPromise[]) {
return new MyPromise((resolve, reject) => {
promises.forEach((p) => {
MyPromise.resolve(p).then(resolve as ThenCB, reject as ThenCB);
// 简化版:
// p.then(resolve as ThenCB, reject as ThenCB);
});
});
}
}
function isNodeEnv() {
if (globalThis.process && globalThis.process.nextTick) {
return true;
}
return false;
}
export function pushToTaskQueue(callback) {
// node 环境用 nextTick
if (isNodeEnv()) {
globalThis.process.nextTick(callback);
return;
}
// 浏览器环境且支持 MutationObserver
if (MutationObserver) {
const ob = new MutationObserver(callback);
const div = document.createElement("div");
ob.observe(div, { childList: true }); // 监听div, 发生变化就执行cb
div.innerHTML = "1";
return;
}
setTimeout(callback);
}
function isFn(v: any) {
return typeof v === "function";
}
function isObj(v: any) {
return typeof v === "object" && v !== null;
}
//
function islikePromise(p: any) {
if ((isObj(p) || isFn(p)) && p.then && isFn(p.then)) {
return true;
}
return false;
}
手写工具函数
🩸实现微队列
- node 环境使用 process.nextTick
- 浏览器环境使用 MutationObserver
function isNodeEnv() {
if (process && process.nextTick) {
return true
}
return false
}
export function pushToTaskQueue(callback) {
// node 环境用 nextTick
if (isNodeEnv()) {
globalThis.process.nextTick(callback);
return;
}
// 浏览器环境且支持 MutationObserver
if (MutationObserver) {
const ob = new MutationObserver(callback);
const div = document.createElement("div");
ob.observe(div, { childList: true }); // 监听div, 发生变化就执行cb
div.innerHTML = "1";
return;
}
setTimeout(callback);
}
🩸 实现promiseLike
- 判断条件
- 是一个对象或函数
- 有then方法
function isFn(v: any) {
return typeof v === 'function'
}
function isObj(v:any) {
return typeof v === 'object' && v !== null
}
function likePromise(p: any) {
if (
(isObj(p) || isFn(p)) && p.then && isFn(p.then)
) {
return true
}
return false
}
🩸 实现Promise.all
Promise.all = function (arr) {
return new Promise((resolve, reject) => {
const values = []
let count = 0
const add = (i, v) => {
values[i] = v
count++
if (count === promises.length) resolve(values)
}
arr.forEach((p, i) => {
// 其实可以写成下面这样, 但p就必须是promise对象,不然会出错
// p.then(
// res => add(i, res),
// rej => reject(rej)
// )
Promise.resolve(p).then(
res => add(i, res),
err => reject(err)
)
})
})
}
🩸 实现catch
catch(onRejected) {
return this.then(null, onRejected)
}
🩸 实现finally
finally(callback: Function) {
return this.then(
res => {
callback() // promise规范: callback不传值
return res // 保留状态一致
},
err => {
callback()
throw err// 保留状态一致
}
)
}
🩸 实现Promise.resolve
// 状态吸收
// const p = Promise.reject("我失败了")
//
// Promise.resolve(p).catch(err => {
// console.log(err) // 👈 输出:我失败了
// })
static resolve(value) {
if (islikePromise(value)) {
return value;
}
return new MyPromise((resolve) => resolve(value));
}
🩸 实现Promise.reject
static reject(reason?) {
return new MyPromise((_, reject) => reject(reason))
}
async await
🩸 return
情况 1:async 函数里啥也不 return
async function fn1() {
console.log(111)
}
等于:
function fn1() {
return new Promise(resolve => {
console.log(111)
resolve(undefind)
})
}
情况 2:async 函数里 return 一个值
async function fn1() {
return 123
}
等于:
function fn1() {
return new Promise(resolve => resolve(123))
}
情况 3:async 函数里 return 一个 Promise
触发状态吸收
const p1 = Promise.resolve(1)
// 生成了新的promise对象
async function fn() {
return p1
}
const p2 = fn()
// p1 不等于 p2, 说明生成了新的promise对象
console.log(p1 === p2) // false
等于:
const p1 = Promise.resolve(1)
// 生成了新的promise对象
function fn() {
return new Promise(resolve => resolve(p1))
}
const p2 = fn()
console.log(p1 === p2) // false
不能这样写:
const p1 = Promise.resolve(1)
function fn() {
return Promise.resolve(p1) // 相当于: return p1
}
const p2 = fn()
console.log(p1 === p2) // true
为什么不能写成 Promise.resolve(xxx)
async 函数一定会创建新 Promise- 状态吸收时
Promise.resolve(p1) === p1, 不会创建新 Promise- 详情去看
Promise.resolve源码
async function fn() {
return p1
}
// 终极一句话总结:
// async 函数的 return,永远等价于:new Promise(resolve => resolve(返回值))
// 绝对不等价于:Promise.resolve(返回值)
// 因为:
// `new Promise` → 一定生成新对象
// `Promise.resolve` → 可能直接返回原来的对象(状态吸收时)
🩸throw error
async function fn1() {
throw 'err info ...'
}
翻译
- 写法1, 写法2, 都可以
- 因为reject没有状态吸收
- 详情去看Promise.reject源码
// 写法1
function fn1() {
return Promise.reject('err info ...')
}
// 写法2
function fn1() {
return new Promise((_, reject) => reject('err info ...'))
}
🩸 async中的状态吸收
// return 了一个promise对象
async function fn1() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(123)
}, 1000)
})
}
等于:
// resolve 了一个promise对象
function fn1() {
const p = new Promise((resolve) => {
setTimeout(() => {
resolve(123)
}, 1000)
})
return new Promise(resolve => resolve(p))
}
🩸 await
案例: C级
async function m(){
const n = await 1;
console.log(n);
// return undefind
}
m();
console.log(2);
翻译:
function m(){
return new Promise(resolve => {
Promise.resolve(1).then(n =>{
console.log(n)
resolve(undefind)
})
})
}
m();
console.log(2);
// 答案: 2,1
极简:
const n = await 1;
console.log(n);
// 等于:
Promise.resolve(1).then(n => {
console.log(n); // 1
})
案例: B级
async function async1() {
console.log(1);
const res = await async2();
console.log(res);
}
async function async2() {
return 2; // return 相当于 resolve
}
async1();
Promise.resolve().then(() => console.log(3));
// 答案: 1,2,3
案例: A级
和上面区别: 多了个await
async function async1() {
console.log(1);
const res = await async2();
console.log(res);
}
async function async2() {
return await 2; // 和上一个例子区别: 多了个await
}
async1();
Promise.resolve().then(() => console.log(3));
答案:
// 答案: 1,3,2
// 1
// r-2, 2
// 3
翻译 return await 1
// fn1 === fn2 === fn3 === fn4 === fn5
async function fn1() {
return await 1
}
// 相当于
async function fn2() {
return await Promise.resolve(1)
}
// 相当于
async function fn3() {
const res = await Promise.resolve(1)
return res
}
// 相当于
function fn4() {
return new Promise(resolve => {
Promise.resolve(1).then(res => resolve(res))
})
}
解析:
// return 相当于 resolve
async function async1() {
console.log(1);
// pending状态, 不会立刻进入微队列
P<pending>.then(res => console.log(res))
}
下面代码, fn1 和 fn2 的区别
- fn1 执行, resolve 立刻执行
- fn2 执行, resolve 被推到微队列执行
- 这就是为什么 p2 的状态为 pending
// 返回的`promise`状态为:success
async function fn1() {
return 666;
}
// 返回的`promise`状态为:pending
// 只要函数里面有await, 那么返回的`promise`状态必为`pengding`
async function fn2() {
return await 666;
}
async function fn11() {
const res = await fn1();
console.log(res);
}
async function fn22() {
const res = await fn2();
console.log(res);
}
// 翻译:
function fn11() {
P1<666>.then(res => console.log(res)) // 立刻进入微队列
}
function fn22() {
P2<pending>.then(res => console.log(res)) // 等待状态确定再进入微队列
}
案例: S级
- 注意
setTimeout前面有一个await
async function async1() {
console.log(1)
await async2()
console.log(2)
}
async function async2() {
await setTimeout(() => {
Promise.resolve().then(() => console.log(3))
console.log(4)
})
}
async function async3() {
Promise.resolve().then(() => {
console.log(6)
})
}
async1()
console.log(7)
async3()
答案:
// 答案: const res = [1, 7, 6, 2, 4, 3]
// 1, 7
// r-2, 2
// 6
// 4
案例: S级
- 注意
setTimeout前面没有await
async function async1() {
console.log(1)
await async2()
console.log(2)
}
// 和上面例子唯一的区别: setTimeout 前面没有await
async function async2() {
setTimeout(() => {
Promise.resolve().then(() => console.log(3))
console.log(4)
})
}
async function async3() {
Promise.resolve().then(() => {
console.log(6)
})
}
async1()
console.log(7)
async3()
答案:
// 答案: const res = [1, 7, 2, 6, 4, 3]
// 1, 7
// 2
// 6
// 4
案例: SSS级
- 考点和上面例题一样, 没什么新的考点
- 可以忽略不看: 出这种题的都是sb
- 看不看看心情
- 区别
- 代码很乱
- 废内存, 需要拿一张纸记录
async function async1() {
console.log(1)
await async2()
console.log(2)
}
async function async2() {
await (async () => {
await (() => {
console.log(3)
})()
console.log(4)
})()
}
async function async3() {
Promise.resolve().then(() => {
console.log(6)
})
}
async1()
console.log(7)
async3()
整理代码
- 规律
- 只要函数里面有await,
- 那么返回的
promise状态必为pengding
async function async1() {
console.log(1);
await async2();
console.log(2);
}
function fn2() {
console.log(3);
}
// 只要里面有await, 返回的promise状态必为pengding
async function fn1() {
await fn2();
console.log(4);
}
async function async2() {
await fn1();
}
async function async3() {
Promise.resolve().then(() => {
console.log(6);
});
}
async1();
console.log(7);
async3();
// 答案 const res = [1, 3, 7, 4, 6, 2]
// 1, 3, 7
// 4, r-2, 2
// 6
案例: SSS级
- 考点和上面例题一样, 没什么新的考点
- 可以忽略不看: 出这种题的都是sb
- 看不看看心情
- 区别
- 代码很乱
- 废内存, 需要拿一张纸记录
async function async1() {
console.log(1)
await async2()
console.log(2)
}
async function async2() {
await (async () => {
Promise.resolve().then(() => console.log(3))
console.log(4)
})()
}
async function async3() {
Promise.resolve().then(() => {
console.log(6)
})
}
async1()
console.log(7)
async3()
整理:
async function async1() {
console.log(1);
await async2();
console.log(2);
}
async function async2() {
async function fn() {
await Promise.resolve().then(() => console.log(3));
console.log(4);
}
await fn();
}
async function async3() {
Promise.resolve().then(() => {
console.log(6);
});
}
async1();
console.log(7);
async3();
// 答案 const res = [1, 7,3,6,4,2]
// 1, 7
// 3, 4, r-2, 2
// 6
状态吸收
🩸 状态吸收的场景
// 状态吸收1
const p6 = Promise.resolve("p6-p6-p6");
const p7 = Promise.resolve(p6);
p7.then((res) => console.log(res));
// // 状态吸收2
const p3 = Promise.reject("err msg p3");
const p4 = Promise.resolve().then(() => p3);
p4.catch((err) => console.log(err));
// // 状态吸收3
const p1 = Promise.reject("err msg ...");
const p2 = new Promise((res) => res(p1));
p2.catch((err) => console.log(err));
🩸 第一题
const p1 = new Promise(resolve => resolve(1))
const p2 = new Promise(resolve => resolve(p1))
console.log(p1)
console.log(p2)
答案
console.log(p1) // Promise { 1 }
console.log(p2) // Promise { <pending> }
状态吸收对应源码:
private resolve(value?: any) {
// 状态吸收只在resolve时发生, reject不发生
if (islikePromise(value)) {
pushToTaskQueue(() => value.then(this.resolve, this.reject));
return;
}
this.changeState("resolved", value);
}
🩸 第二题
async function fn1() {
console.log(1)
await fn2()
console.log("AAA")
}
function fn2() {
return Promise.resolve(2)
}
fn1()
Promise.resolve()
.then(() => console.log(3))
.then(() => console.log(4))
.then(() => console.log(5))
翻译
async function fn1() {
console.log(1)
fn2().then(() => console.log("AAA"))
}
function fn2() {
return Promise.resolve(2)
}
fn1()
Promise.resolve()
.then(() => console.log(3))
.then(() => console.log(4))
.then(() => console.log(5))
答案分析
// 1
// AAA
// 3, 4, 5
// 答案: 1, 'AAA', 3, 4, 5
// 执行: fn2().then(() => console.log("AAA"))
// 添加微任务: () => console.log("AAA")
[
() => console.log("AAA")
]
// 执行: Promise.resolve().then(() => console.log(3))
// 添加微任务: () => console.log(3)
[
() => console.log("AAA"),
() => console.log(3)
]
// 执行 () => console.log("AAA") 没有产生新的微任务
// 执行 () => console.log(3)
// 添加微任务 () => console.log(4)
[
() => console.log(4)
]
//执行 () => console.log(4)
//添加微任务 () => console.log(5)
[
() => console.log(5)
]
🩸 第三题
async function fn1() {
console.log(1)
await fn2()
console.log("AAA")
}
// 与第二题不同的地方fn2: 多了一个 async
// 在 async 函数中, return 一个promise对象, 就相当于resolve一个promise对象
async function fn2() {
return Promise.resolve(2)
}
fn1()
Promise.resolve()
.then(() => console.log(3))
.then(() => console.log(4))
.then(() => console.log(5))
翻译
async function fn1() {
console.log(1)
fn2().then(() => console.log('AAA'))
}
function fn2() {
return new Promise((resolve) => {
const p1 = Promise.resolve(2)
resolve(p1)
})
}
fn1()
Promise.resolve()
.then(() => console.log(3))
.then(() => console.log(4))
.then(() => console.log(5))
答案分析
// 1,
// then(r-AAA), r-AAA, AAA
// 3, 4, 5
// 打印结果为: 1, 3, 4, 'AAA', 5
// 同步任务
[
console.log(1)
]
// 微任务
[
// 谁生成的该微任务:
// resolve(p1)
() => p1.then(resolve)
// 谁生成的该微任务:
// Promise.resolve().then(()=>console.log(3))
() => console.log(3)
// 谁生成的该微任务:
// () => p1.then(resolve)
() => resolve()
// 谁生成的该微任务:
// () => console.log(3)
() => console.log(4)
// 谁生成的该微任务:
// () => resolve()
() => console.log("AAA")
// 谁生成的该微任务:
// () => console.log(4)
() => console.log(5)
]
源码
private resolve(value?: any) {
// 状态吸收只在resolve时发生, reject不发生
if (islikePromise(value)) {
pushToTaskQueue(() => value.then(this.resolve, this.reject));
return;
}
this.changeState("resolved", value);
}
🩸 第四题
const p1 = new Promise((resolve) => resolve(1))
const p2 = new Promise((resolve) => resolve(p1))
p2
.then(() => console.log(1))
.then(() => console.log(2))
.then(() => console.log(3))
p1
.then(() => console.log(4))
.then(() => console.log(5))
.then(() => console.log(6))
答案
// then(r-1), r-1, 1, 2, 3
// 4, 5, 6
// 答案: 4, 5, 1, 6, 2, 3
// 微队列
[
() => p1.then(resolve),
() => console.log(4),
() => resolve(),// 添加者:() => p1.then(resolve),
() => console.log(5),//添加者:() => console.log(4)
() => console.log(1),//添加者:() => resolve()
() => console.log(6),//添加者:() => console.log(5)
() => console.log(2),//添加者:() => console.log(1)
() => console.log(3),//添加者:() => console.log(2)
]
🩸 第五题
Promise.resolve()
.then(() => {
console.log(0)
return Promise.resolve(4)
})
.then(res => console.log(res))
Promise.resolve()
.then(() => console.log(1))
.then(() => console.log(2))
.then(() => console.log(3))
.then(() => console.log(5))
答案
// 0, then(r-4), r-4, 4,
// 1, 2, 3, 5
// 答案: 0,1,2,3,4,5
const microTask = [
() => {
console.log(0)
return Promise.resolve(4) // return p4
},
() => console.log(1),
() => p4.then(resolve),
() => console.log(2),
() => resolve(4),
() => console.log(3),
(res) => console.log(res), // res=4
() => console.log(5),
]
对应源码
const x = thenCB(value);
if (islikePromise(x)) {
pushToTaskQueue(() => x.then(nextPromise.resolve, nextPromise.reject));
return;
}
其他面试题
🩸 交替执行
Promise.resolve()
.then(() => console.log(1))
.then(() => console.log(2))
.then(() => console.log(3));
Promise.resolve()
.then(() => console.log(10))
.then(() => console.log(20))
.then(() => console.log(30));
Promise.resolve()
.then(() => console.log(100))
.then(() => console.log(200))
.then(() => console.log(300));
答案
// 1,2,3
// 10, 20, 30
// 100, 200, 300
// 答案:
// 1
// 10
// 100
// 2
// 20
// 200
// 3
// 30
// 300
🩸 catch error
案例1
Promise.resolve()
.then(res => {
console.log('---------- 111') // √
throw new Error()
})
.catch(err => {
console.log('---------- 222') // √
})
.then(res => {
console.log('---------- 333') // √
})
案例2
Promise.resolve()
.then(res => {
console.log('---------- 111') // √
throw new Error()
})
.catch(err => {
console.log('---------- 222') // √
})
.catch(res => {
console.log('---------- 333')
})
🩸 事件循环
setTimeout(() => {
console.log(1)
})
const p = new Promise(resolve => {
console.log(2)
resolve(3)
Promise.resolve(4).then(console.log)
console.log(5)
}).then(console.log)
console.log(6)
解析
const p = new Promise(resolve => {
console.log(2)
resolve(3) // 注意:此时 Promise 的 then 方法尚未注册
Promise.resolve(4).then(console.log)
console.log(5)
}).then(console.log)
答案
// 2,5,6
// 4
// 3
// 1
// 答案: [2, 5, 6, 4, 3, 1]
const res = [2, 5, 6, 4, 3, 1]
const macroTask = [
() => console.log(1),
]
const microTask = [
() => console.log(4),
() => console.log(3),
]
🩸 构造函数
new Promise((resolve, reject) => {
reject(1)
console.log(2)
resolve(3)
console.log(4)
})
.then(res => console.log(res))
.catch(err => console.log(err))
try {
new Promise((resolve, reject) => {
throw 6
})
.then(console.log)
.catch(err => console.log(8))
} catch (error) {
console.log(error)
}
答案
// 2, 4,
// r-1, 1
// r-8, 8
// 答案
const res = [2, 4, 1, 8]
🩸 微任务
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve();
console.log(2);
})
promise.then(() => {
console.log(3);
})
console.log(4);
// 答案: 1,2,4,3
// 1, 2, 4
// 3
🩸 宏任务+微任务
const promise = new Promise((resolve, reject) => {
console.log(1);
setTimeout(()=>{
console.log(2)
resolve(null);
console.log(3);
})
})
promise.then(() => {
console.log(4);
})
console.log(5);
// 答案: 1,5,2,3,4
🩸 透传
例1
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
const promise2 = promise1.catch(() => {
return 2;
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
console.log('promise1', promise1)
console.log('promise2', promise2)
}, 2000)
翻译
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
const promise2 = promise1.then(
null,
() => 2
)
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
console.log('promise1', promise1)
console.log('promise2', promise2)
}, 2000)
// 答案:
// promise1 Promise { <pending> }
// promise2 Promise { <pending> }
// promise1 Promise { 1 }
// promise2 Promise { 1 }
例2
Promise.resolve()
.then(res => {
console.log('---------- 111') // √
})
.catch(err => {
console.log('---------- 222')
})
.then(res => {
console.log('---------- 333') // √
})
解析
Promise.resolve()
.then(res => console.log('---------- 111'))// √
.then(null, err => console.log('---------- 222'))
.then(res => console.log('---------- 333'))// √
例3
const p1 = Promise.reject()
.then(() => console.log(1))
.then(() => console.log(2))
.catch(() => console.log(3));
const p2 = Promise.resolve()
.then(() => console.log(4))
.then(() => console.log(5));
答案
// r, r, 3
// 4, 5
// 答案: 4, 5, 3
解析
// 不会看源码
[
reject1,
console.log(4),
reject2
console.log(5)
console.log(3)
]