zoukankan      html  css  js  c++  java
  • 关于promise的几个认知

    1. 为什么要有promise

    ···从代码上来说回避了回调嵌套的问题,其次promise可以保留异步请求的状态(即使得到结果不立刻执行回调,过一阵再执行仍然是可以的。)

    ···从思想上来说,我们设计一连串事件abc的思路是,先做a,a行的话做b,a不行做f。b行的话做c,b不行那也做f。最后c行就成功了,c不行还是做f。原始的回调函数写出来是这样的思路:a行的话做b,b行的话做c,c行的话成功,c不行做f,b不行做f,a不行做f。那么Promise显然更符合自然逻辑。

    2. promise的API:http://www.tuicool.com/articles/fMJJBze

    自己实现一个Promise:https://github.com/xieranmaya/blog/issues/3

    (这个Promise与原生promise不同,它的resolve里直接执行了回调函数,而不是由then放进promiseJob的队列放在本轮末尾执行) 

    3.promise的回调为什么要在microtask中,在本轮event loop的最后执行,而不是像setTimeOut一样在下一轮event loop中执行?

    我们在promise的executor中可以传入异步操作的代码(当然也可以是同步),那么就分为两种情况。

    ···发送异步请求--根据结果调用resolve改变promise状态--再调用回调的过程。

    ···执行同步代码--resolve立即执行改变了promise状态--调用回调

    对于第一种情况,promise比传统方法多一步回调。异步操作的回调肯定是在macrotask中在后一个event loop中执行,试想如果promise的回调也在macrotask中,那么这个异步操作从发出请求到执行最终then方法里的回调函数,就需要耽搁两次,这当中可能会有其他任务插进来,而第二次是没必要的。所以把promise的回调放在microtask中处理,可以确保在异步返回请求后的同一轮eventloop中执行。

    那么把promise注册的回调改为同步行不行呢,在异步操作里是没有问题的,因为then会在resolve执行前就注册好回调,但是对于第二种情况,如果是执行同步代码,那么resolve立即执行了,此时then方法还没有执行,没有注册上回调函数。所以不管是哪种情况,在本轮eventloop的最后执行then回调是最好的。

    实际上,调用resolve或reject实际上是改变当前Promise实例的状态(pending->fulfilled,或pending-rejected),并附带传给Promise实例一个state值而已,并不是要执行其他处理。

    而我们通过then来订阅Promise实例的状态变化,而这个状态变化的事件通知有3个特点:
    1. 异步触发:就是状态变化后不会马上执行事件响应函数,而是等待当前任务队列为空时才执行;
    2. 仅触发一次:由于Promise实例的状态变化是单向不可逆,因此同一个事件响应函数仅能被执行一次;
    3. 延迟绑定:虽然我们订阅的是状态变化事件,但即使实例的状态已经为fulfilled或rejected,我们才订阅事件,依然可以得到触发。

  • 相关阅读:
    const 与 readonly知多少
    js中得~~是什么意思/JS按位非(~)运算符与~~运算符的理解分析
    严格模式详解
    Javascript中的prototype和__proto__的联系区别
    提升页面渲染效率
    window.onload=function(){}和$(function(){})的区别
    gulp的安装和配置
    JS的组成部分、引入页面的方法以及命名规范
    js继承的三种实现
    前端模块化
  • 原文地址:https://www.cnblogs.com/natsu07/p/6498077.html
Copyright © 2011-2022 走看看