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 如此循环

 

posted @ 2017-11-10 15:03  dunker  阅读(708)  评论(0编辑  收藏  举报