promise用法十道题
JS是单线程语言,多数的网站不需要大量计算,程序耗时主要是在磁盘I/O和网络I/O上 ,虽然固态硬盘SSD读取很快,但是和CPU比起来却不在一个数量级上,而且网络上的一个数据包来回时间更慢,所以一些CPU直接执行的任务就是主线程任务优先执行,随之就有了同步任务(主线程排队执行的任务前一个执行完毕才执行下一个)和异步任务(不进入主线程,而进入任务队·task queue·,等主线程执行完才开始执行)之分。任务队列又分为microtask(①process.pbservw②promise③Object.observer④MutationObserve)和macrotask(setTimeout、setInterval和setImmediate、i/o和UI渲染)
每个事件循环event loop会有一个以上task queue==macrotask queue 值得注意的是每个包裹在script标签中的代码也是一个macrotask。
事件循环的顺序决定了js代码执行的顺序,它从整体代码开始第一次循环,之后全局上下文进入函数调用栈,直到调用栈清空,只剩下全局,然后执行所有的micro task.当所有的micro task执行完毕循环再次从macro task开始找到其中一个任务队列执行完毕,然后执行再执行micro task,这样一直循环下去
ex1:
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(因为promise.then中的函数是异步执行的)
ex2:
const promise1 =new promise((resolve,reject)=>{
setTimeout(
()=>{resolve('success')}
,100)
})
const promise2 = promise1.then(
()=>{throw new Error('erro')}
)
console.log('promise1',promise1)
console.log('promise2',promise2)
setTimeout(()=>{
console.log('promise1',promise1)
console.log('promise2',promise2)
},2000)
结果是 :promise1 Promise{<pending>}
promise2 Promise{<pending>}
(node:50928) ....
因为promise有三种状态,状态一旦改变就凝固不可逆 上面的promise2并不是promise1 而是返回一个新的Promise实例
ex3:const promise = new Promise(()=>{
resolve('success'),
reject('error')
})
Promise.then((res)=>{
console.log('then':res)
}).catch((err)=>{
console.log('catch',err)
})
结果:then:success1
构造函数中的resolve或reject 只有第一次执行有效,多次调用是没有效果的,因为其状态一旦改变就凝固
另外链式操作可以用return this 实现 promise 每次调用.then 或.catch都会返回一个新的promise从而实现了链式操作。
Promise的.then和.catch的参数期望值是函数,传入的非函数则会发生值穿透
事件循环起始于all scripts 是属于task(macro task)然后在主线程run 期间将ticks promise压入miscro task ,setTimeout压入macro task剩下的cobnsole.log直接执行,然后开始执行一遍micro task 这是考虑ticks优先级大于promise 所以输出s ticks在前,当micro task执行完了又去执行一个macro task 然后又清Micro task一遍再去执行macro task 如此循环


浙公网安备 33010602011771号