最近在准备面试的过程中,深入学习了一下Promise对象,之前学ES6的时候一直没有深入研究过Promise,现在发现这个东西还是挺重要的,综合自己这几天来看阮一峰前辈的ES6博客和一些教学视频,总结出一些Promise的相关概念及面试题,以后忘记的时候还能回来看看
Promise是ES6用来解决异步操作的一个方案,用来防止传统事件+回调容易造成的问题;主要的问题有:
1:回调嵌套太深,难以阅读和维护
2:无法正常使用return,tyr cactch
3:回调之间难以建立联系
当然node7.6已经支持ES7了,ES7采用的是async await的解决方案,这个先暂且不谈
function promise(){
return new Promise((resolve, reject) => {
resolve('haha')
}).then(function(data){
console.log(data);
return data + 'heihei';
}).then(function(data){
console.log(data);
})
}
// haha
// hahaheihei
从上面的demo可以看出,resolve()里面的数据可以直接抛过来,但是在链式操作的时候,我们需要return data。
另外一点是,我们可以针对不同的情况来选择是resolve还是reject,比如说
function promise(){
return new Promise((resolve, reject) => {
if(10%2){
resolve();
}else{
reject();
}
}).then(function(){
console.log('真淘气');
}).catch(function(){
console.log('顽皮');
})
}
// 顽皮
另外两个常用的promise方法是promise.all()和promise.race()
这两个方法都是接受一个由promise对象组成的数组作为参数
顾名思义,第一个是all,全部的,也就是说数组里的每一个promise都完成了resolve,那么才算成功,才会走then。
而第二个是race,就竞赛的意思,那么也就是说当数组里只要有一个promise对象完成了resolve(), 那么它就会往下执行了。
下面放上关于Promise的几道面试题!
setTimeout(function(){
console.log(1);
}, 0)
new Promise(function executor(resolve){
console.log(2);
for(var i = 0; i < 1000; i++){
i = 9999 && resolve();
}
console.log(3);
}).then(function(){
console.log(4);
})
console.log(5);
之前说过,在定时器,事件,ajax等操作的时候,会使一个异步操作,会把该操作放到一个task queue里,需要等当前主线程的任务完成后,会读取任务队列(task queue)中的是事件。
那么,setTimeout会放到任务队列中,代码继续往下走。
所以先输出2 3。
promise中的then操作是放在执行栈,也就是主线程的最后。
那么主线程会继续往下走咯。
所以输出 5 4
最后主线程的任务搞完了,才会去执行task queue中的任务。
所以最后执行1
// 2, 3, 5, 4, 1