先来个例子
一、例子1
setTimeout(function(){
console.log('4定时器开始啦')
});
new Promise(function(resolve){
console.log('1马上执行for循环啦');
for(var i = 0; i < 10000; i++){
i == 99 && resolve();
}
}).then(function(){
console.log('3执行then函数啦')
});
console.log('2代码执行结束');
先别看下面的答案,自己先想想执行顺序。
image.png二、例子2
如果把 console.log('2代码执行结束');
放在最前面呢?
console.log('2代码执行结束');
setTimeout(function(){
console.log('4定时器开始啦')
});
new Promise(function(resolve){
console.log('1马上执行for循环啦');
for(var i = 0; i < 10000; i++){
i == 99 && resolve();
}
}).then(function(){
console.log('3执行then函数啦')
});
image.png
三、例子3
console.log(1)
setTimeout(function(){
console.log(5)
})
Promise.resolve().then(function(){
console.log('promise3')
}).then(function(){
console.log('promise4')
})
console.log(2)
image.png
四、例子4
console.log(1)
setTimeout(() => {
console.log(5)
})
new Promise((resolve, reject) => {
console.log(2); for (let i = 0; i < 10000; i++) {
i == 99 && resolve();
}
}).then(() => {
console.log('promise4')
})
console.log(3)
image.png
五、例子5
console.log(1)
setTimeout(() => {
console.log(5)
})
new Promise((resolve, reject) => {
console.log(2);
setTimeout(() => {
console.log(4);
resolve()
}, 6000)
}).then(() => {
console.log('promise5')
})
console.log(3)
image.png
六、例子6
setTimeout(() => {
console.log('3setTimeout');
})
new Promise((resolve) => {
console.log('1promise');
setTimeout(() => {
resolve()
}, 3000)
}).then(() => {
console.log('4then');
})
console.log('2console');
image.png
七、例子7
console.log('1111111');
setTimeout(() => {
console.log('4----');
new Promise((resolve) => {
console.log('5-----');
resolve();
}).then(() => {
console.log('6----')
})
})
new Promise((resolve) => {
console.log('22222');
resolve();
}).then(() => {
console.log('33333-----')
})
setTimeout(() => {
console.log('77777');
new Promise((resolve) => {
console.log('888');
resolve();
}).then(() => {
console.log('9999999')
})
})
image.png
八、例子8
这个例子有点难度:
const first = () => (new Promise((resolve, reject) => {
console.log(11111);
const p = new Promise((resolve, reject) => {
console.log('222222' + 'new Promise');
setTimeout(() => {
console.log(66666);
resolve('77777--0000'); // 虽然这里又有一次p的 resolve 但是p的then的语句不会再执行了
}, 0)
resolve('4444444' + 'p');
});
resolve('555555' + 'first');
p.then((arg) => {
console.log(arg); // p 第一次被resolve后 第二次再resolve 不会再执行了
});
}));
first().then((arg) => {
console.log(arg);
});
console.log(333333);
image.png
上面有一点值得注意,就是p的状态一旦改变了(resolve)就不会再改变了,所以 resolve('77777--0000')
不会执行了
九、例子9 (promise状态不可逆性)
var p1 = new Promise(function(resolve, reject){
console.log('我是p1 我会立即执行')
resolve("success1");
resolve("success2");
});
var p2 = new Promise(function(resolve, reject){
console.log('我是p2 我会立即执行')
resolve("success");
reject("reject");
});
p1.then(function(value){
console.log(value);
});
p2.then(function(value){
console.log(value);
});
image.png
十、例子10
var p = new Promise(function(resolve, reject){
console.log("1create a promise");
resolve("3success");
});
console.log("2after new Promise");
p.then(function(value){
console.log(value);
});
image.png
十一、例子11 链式调用返回值
var p = new Promise(function(resolve, reject){
resolve(1);
});
p.then(function(value){ //第一个then
console.log(value);// 1
return value*2;//2
}).then(function(value){ //第二个then
console.log(value+3);//5
}).then(function(value){ //第三个then
console.log(value+"后面是 return Promise.resolve('resolvePromise')");// resolvePromise
return Promise.resolve('resolvePromise');//
}).then(function(value){ //第四个then
console.log(value+'后面是 return Promise.reject(\'rejectPromise\')');// rejectPromise
return Promise.reject('rejectPromise');//
}).then(function(value){ //第五个then
console.log('resolve: '+ value);
}, function(err){
console.log('reject: ' + err); // reject:rejectPromise
})
image.png
十二、例子12 回调异步性
var p = new Promise(function(resolve, reject){
console.log('我最先执行')
resolve("我在console.log(\"which one is called first ?\")后执行");
});
p.then(function(value){
console.log(value); //
});
console.log("which one is called first ?");//
image.png
十三、例子13 Promise 中的异常
var p1 = new Promise( function(resolve,reject){
foo.bar();
resolve( 1 );
});
p1.then(
function(value){
console.log('p1 then value: ' + value);//
},
function(err){
console.log('p1 then err: ' + err);
}
).then(
function(value){
console.log('p1 then then value: '+value); //
},
function(err){
console.log('p1 then then err: ' + err);
}
);
var p2 = new Promise(function(resolve,reject){
resolve( 2 );
});
p2.then(
function(value){
console.log('p2 then value: ' + value);
foo.bar();
},
function(err){
console.log('p2 then err: ' + err);
}
).then(
function(value){
console.log('p2 then then value: ' + value);
},
function(err){
console.log('p2 then then err: ' + err);
return 1;
}
).then(
function(value){
console.log('p2 then then then value: ' + value);
},
function(err){
console.log('p2 then then then err: ' + err);
}
);
image.png
上面值得注意的是 p1、 p2 的多级then回调函数是交替进行的
十四、例子 Promise.resolve()
var p1 = Promise.resolve( 1 );
var p2 = Promise.resolve( p1 );
var p3 = new Promise(function(resolve, reject){
resolve(1);
});
var p4 = new Promise(function(resolve, reject){
resolve(p1);
});
console.log(p1 === p2);
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);
p4.then(function(value){
console.log('p4=' + value);
});
p2.then(function(value){
console.log('p2=' + value);
})
p1.then(function(value){
console.log('p1=' + value);
})
image.png
上面说明下:1、p3 和p4 不和其他相等 是因为 new 出来的对象 不会相等;2、console.log('p4=' + value);
放在最前面 但是最后执行 是因为 p4里面要resolve p1 而p1 又是一个Promise对象,resolve会对p1”拆箱“ 进而获取p1的状态值 但是这是个异步过程 因此 它最后执行;
十五、例子 15 resolve vs reject 拆箱功能
var p1 = new Promise(function(resolve, reject){
resolve(Promise.resolve('resolve'));
});
var p2 = new Promise(function(resolve, reject){
resolve(Promise.reject('reject'));
});
var p3 = new Promise(function(resolve, reject){
reject(Promise.resolve('resolve'));
});
p1.then(
function fulfilled(value){
console.log('p1 fulfilled: ' + value);
},
function rejected(err){
console.log('p1 rejected: ' + err);
}
);
p2.then(
function fulfilled(value){
console.log('p2 fulfilled: ' + value);
},
function rejected(err){
console.log('p2 rejected: ' + err);
}
);
p3.then(
function fulfilled(value){
console.log('p3 fulfilled: ' + value);
},
function rejected(err){
console.log('p3 rejected: ' + err);
}
);
image.png
这里稍微解释下 1、为啥p3在最后写 却最先执行了 因为p3 执行的是reject 所以其不需要进行拆箱,因此不会像p1和p2 那样需要拆箱才能异步拿到结果;2、为啥p2 没有执行 fulfilled 回调 因为 p2 在创建时 拆箱得到的结果是reject 因此走的是 rejected 函数的回调而不是fulfilled ;
参考及推荐资料
1、这一次,彻底弄懂 JavaScript 执行机制
2、一个Promise面试题
3、八段代码彻底掌握 Promise
网友评论