博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Promise 基本原理 & 异步
阅读量:7135 次
发布时间:2019-06-28

本文共 3513 字,大约阅读时间需要 11 分钟。

author: 陈家宾email: 617822642@qq.comdate: 2018/2/23

Promise 基本实现

var PENDING = 0;var FULFILLED = 1;var REJECTED = 2;function Promise(fn) {    var state = PENDING;    var value = null;    var handlers = [];    doResolve(fn, resolve, reject)    function fulfill(result) {}    // state=fulfilled, value=result    function reject(error) {}    // state=rejected, value=error    function resolve(result) {}    // if then in result(result 是个 promise), 执行 doResolve    // else 执行 fulfill        function doResolve(fn, onFulfilled, onRejected) {}    // 给 fn 传入 resolve 和 reject 函数    // resolve 函数,执行 onFulfilled    // reject 函数,执行 onRejected        function handle(handler) {}    // if PENDING, push handler    // if FULFILLED, 执行 handler 中的 onFulfilled 函数    // if REJECTED, 执行 handler 中的 onRejected 函数        this.done = function (onFulfilled, onRejected) {}    // 异步(setTimeout 0)执行 handler({onFulfilled, onRejected})        this.then = function (onFulfilled, onRejected) {        var self = this        return new Promise((resolve,reject)=>{            return self.done(result=>{                if onFulfilled                    return resolve(onFulfilled(result))                else                     return resolve(result)            }, err=>{                if onRejected                    return resolve(onRejected(err))                else                    return reject(err)            })        })    }}

基本语法

new Promsie((resolve, reject) => {    // function1()    resolve()}).then(() => {    // function2()})

这里 function1 同步执行,function2 异步执行

Promise 本轮循环 & 次轮循环

本来以为 Promise 的内容就到此为止了,后来看到了阮老师的一篇博客,里面说异步分两种,what?!!

异步任务可以分成两种。

  • 追加在本轮循环的异步任务
  • 追加在次轮循环的异步任务

Node 规定,process.nextTickPromise的回调函数,追加在本轮循环,即同步任务一旦执行完成,就开始执行它们。而setTimeoutsetIntervalsetImmediate的回调函数,追加在次轮循环。

异步分两种已经让我大开眼界,但在我的知识世界里,Promise 不是用 setTimeout 来实现异步的吗,为什么 Promise 和 setTimeout 还分属于不同的异步类型里呢?

OK,马上找一下 Promise 的

if (isNode) {  scheduleFlush = useNextTick();} else if (BrowserMutationObserver) { // BrowserMutationObserver = window.MutationObserver  scheduleFlush = useMutationObserver();} else if (isWorker) { // typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'  scheduleFlush = useMessageChannel();} else if (browserWindow === undefined && typeof require === 'function') { // browserWindow = typeof window !== 'undefined' ? window : undefined  scheduleFlush = attemptVertx();} else {  scheduleFlush = useSetTimeout();}

原来 Promise 的异步不仅仅只是 setTimeout,这里会根据不同环境来采用不同的实现方式,浏览器中主要用了 MutationObserver 和 setTimeout

我们先来看一下 MutationObserver 的兼容性(下图参考 )

由上图可知,使用 polyfill,从以上版本开始,Promise 是由 MutationObserver 实现的本轮循环的异步任务,低于以上版本的,则是由 setTimeout 实现的次轮循环的异步任务(本轮循环在次轮循环之前执行)。其带来的具体差别如下:

// ie11setTimeout(function () {console.log(1)});Promise.resolve().then(function () {  console.log(2);});// 输出结果为 2 1// ie10setTimeout(function () {console.log(1)});Promise.resolve().then(function () {  console.log(2);});// 输出结果为 1 2

其他

shim VS polyfill

  • shim,给浏览器带来新 API 的库,如 jQuery
  • polyfill 则是针对浏览器的一种补丁,一种补充,使其行为与其他浏览器保持一致,如 promise-polyfill

单词 polyfill 的由来:

Polyfilla is a UK product known as Spackling Paste in the US. With that in mind: think of the browsers as a wall with cracks in it. These [polyfills] help smooth out the cracks and give us a nice smooth wall of browsers to work with.——Remy Sharp

参考资料

  1. 《Node 定时器详解》,阮一峰,2018年2月23日,
  2. What is the difference between a shim and a polyfill? ,stack overflow,closed at Jul 30 '15,
  3. 《Speaking JavaScript》,Axel Rauschmayer,March 2014,

转载地址:http://dgvrl.baihongyu.com/

你可能感兴趣的文章
echo
查看>>
MariaDB,MySQL中存储过程的学习笔记
查看>>
一张图诠释linux系统启动过程
查看>>
载入jQuery库的最佳方法
查看>>
系统错误提示修复Repair Filesystem
查看>>
【DAY20】Socket编程的补充2
查看>>
Openstack 网络服务Neutron [五]
查看>>
如何看硬盘SMART参数----用HDtune工具查看
查看>>
PUTTY使用Ctrl+s僵死的问题
查看>>
单链表逆序、反转
查看>>
查询表空间是否是设置了自增
查看>>
《深入理解Java虚拟机》读后总结(二)JVM内存分配
查看>>
cisco 用户权限级别管理
查看>>
Oracle 审计失败的用户登陆(Oracle audit)
查看>>
成都高薪PHP工程师
查看>>
如何评价小米手机第二代M2
查看>>
JavaScript最经典的55个技巧(转)
查看>>
恢复mysql的root密码与权限
查看>>
Java 处理图片 base64 编码的相互转换
查看>>
Magento入门基础 - 在magento后台增加一个自定义订单状态
查看>>