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);
}).then(() => {
console.log(6);
})
###这个和promise A+规范里,.then对传递函数结果的判定有关。。文字描述有点费力,贴一下之前按照promise A+实现的简易promise代码。
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const resolvePromise = (promise,x,resolve,reject)=>{
// 1. promise===x reject错误
// 2. x是Promise函数, 将x的结果放入resolve和reject
// 3. x是普通值,将x直接resolve
if(promise === x){
reject(TypeError('xxxxxx......'))
return;
}
// 一般会判断x是对象,且x.then是方法,主要是为了应对和其他满足promise规范发Promise混用时的情况,此处简单点判断。。
// if(x instanceof myPromise){
if(typeof x?.then === 'function'){
x.then((res)=>{ // 因为then函数return的是promise,因此x的状态需向上一层的promise传递
resolve(res)
},(rej)=>{
reject(rej)
})
return;
}
resolve(x)
}
class myPromise {
static resolve(val){
return new myPromise(res=>{
res(val)
})
}
constructor(fn) {
this.status = PENDING
this.value = null
this.reason = null
this.resArr = []
this.rejArr = []
const resolve = (val) => {
this.value = val
this.status = FULFILLED
this.resArr.forEach(func=>func())
}
const reject = (reason) => {
this.reason = reason
this.status = REJECTED
this.rejArr.forEach(func=>func())
}
fn(resolve, reject)
}
then(onFulfilled,onReject) {
const promise2 = new myPromise((res,rej)=>{
if(this.status===FULFILLED){
setTimeout(()=>{
const x = onFulfilled(this.value)
resolvePromise(promise2,x,res,rej)
})
}else if(this.status===PENDING){
this.resArr.push(()=>{
const x = onFulfilled(this.value)
resolvePromise(promise2,x,res,rej)
})
this.rejArr.push(()=>{
onReject(this.reason)
})
}
})
return promise2;
}
catch(fn) {
this.rejArr.push(fn)
this.status = REJECTED
}
}
const test = ()=>{
return new myPromise((res,rej)=>{
setTimeout(()=>{
res('step 1, ok');
}, 1000)
}).then(val=>{
console.log(val);
return new myPromise((res,rej)=>{
setTimeout(()=>{
res('step 2,ok')
},1500)
})
}).then(val=>{
console.log(val)
})
}
const testFunc = async ()=>{
const ts = new myPromise(res=>{setTimeout(()=>{res('100');console.log('ok')},2000)})
const res = await ts
console.log(res)
}
module.exports = myPromise;
先把代码里的setTimeout都当作微任务看,你return Promise.resolve(4)的操作实际走了.then里的第一个判断,.then返回的promise在reslove之前经过了两次setTimeout的等待
###早上我一眼看到的时候也一脸问号,不过找到一篇博客,你可以看下,讲的很细仔了。Promise.then链式调用顺序 - 高先生的猫
###简单鲁个promise就明白了
const Promis = function(res){
this.resolveArr = [];
res && res(this.resolve.bind(this));
};
Promis.prototype.then = function(fn){
this.resolveArr.push(fn);
return this;
};
Promis.prototype.resolve = function(){
setTimeout(()=>{
this.resolveArr.forEach(fn => {
fn && fn()
})
},0)
}
new Promis(res=>{
console.log(1)
res()
}).then(()=>{console.log(2)}).then(()=>{console.log(3)})
其实是先执行的then,把回调都push到数组里,resolve的时候一个一个调。
###https://segmentfault.com/a/11...
###这是个 microtask
奇葩入队问题啊,并不涉及宏任务。
我的结论是:
下边这句代码会生成两个(没有log的)微任务return Promise.resolve(4);
我的推理很简单
第一步,搞清楚去掉这句后,两个平行的promise链是如何入队的。
只有一个条promise链的情况下,是执行到then的时候才会入队。现在有两个,测试一下
Promise.resolve().then(() => {
console.log(0);
}).then(() => {
console.log(2)
}).then(() => {
console.log(4)
}).then(() => {
console.log(6)
})
Promise.resolve().then(() => {
console.log(1);
}).then(() => {
console.log(3);
}).then(() => {
console.log(5);
}).then(() => {
console.log(7);
})
输出是 0 1 2 3 4 5 6 7
发现顺序是 上边入一个,下边入一个
拉直
我得出的结论是,两条平行promise链,是有序逐链跳跃入队的
所以加上这句后,也应该是跳跃入队的,
原题:
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);
}).then(() => {
console.log(6);
})
输出 0 1 2 3 4 5 6
经过测试,这句会被卡2次
说明这句插入了两个没有log的微任务。
验证一下:给另一条链也加一句,抵消一下
Promise.resolve().then(() => {
console.log(0);
return Promise.resolve(2);
}).then((res) => {
console.log(res)
}).then(() => {
console.log(4);
})
Promise.resolve().then(() => {
console.log(1);
return Promise.resolve(3);
}).then((res) => {
console.log(res)
}).then(() => {
console.log(5);
})
猜结果?
答案 0 1 2 3 4 5
换个位置:
Promise.resolve().then(() => {
console.log(0);
})
.then(() => {
console.log(2)
}).then(() => {
console.log(4)
}).then(() => {
console.log(6)
}).then(() => {
console.log(7)
}).then(() => {
console.log(8)
}).then(() => {
console.log(10)
})
Promise.resolve().then(() => {
console.log(1);
}).then(() => {
console.log(3);
}).then(() => {
console.log(5);
return Promise.resolve(9);
}).then(res =>{
console.log(res)
})
答案 0 1 2 3 4 5 6 7 8 9 10