最近一个体量很小的 JavaScript 库is-promise(npm地址:https://www.npmjs.com/package/p-is-promise,Githubf地址:https://github.com/sindresorhus/p-is-promise)进行了更新,由于最新版本没有遵循正确的 ES 模块标准,使得超过300万个引用了is-promise的前端项目均出现了问题,这个问题甚至让整个 JavaScript 生态系统陷入了混乱。由于前端项目的构造方式与中后台项目的机制不同,这种由小型项目引起广泛问题的情况已经不是第一次发生了。

前两天小扎的FaceBook也因为SDK中的两行代码使很多IOS的应用全部陷入了崩溃的境地。

而当笔者看到这样的新闻,心中不由得一颤,因为前端恰恰司徒正美老师生前一直奋斗的领域,而我来写这篇文章,执笔当哭,缅怀旧人。

//创建一个Promise对象,定义resolve方法,在3000ms后执行。const promise1 = new Promise(function(resolve, reject) {setTimeout(function() {resolve('promise');}, 3000);});//非阻塞执行promise1,在promise完成后此方法会被执行。promise1.then(function(value) {console.log(value);// 3s后会输出promise});console.log(promise1);//直接输出 [object Promise]

笔者和司徒结识于CSDN,记得是去年6月,当时我看到一篇博文《前端开发 20 年变迁史》,心中不由赞叹,竟有人能将前端技术上升到哲学高度来进行阐释,于是千方百信找到了司徒的微信加为好友,和司徒聊天中,明显能感受到他对于前端技术的理解深度和积极热情。谁知天有不测风云,司徒年纪轻轻竟然溘然长逝,在此笔者也提示各位读者朋友们保重身份,切莫透支健康。下面笔者就尝试代替司徒,帮助大家解读一下这则新闻背后的技术细节。由于前端并不是笔者的领域,如有错漏还请各位指正。

初识promise

因为笔者对于JavaScript也不是特别了解,而初步学习了之后我看到了阻塞代码,非阻塞代码,事件驱动设计模式,事件生命周期,函数堆栈,事件队列,等等概念,以及polyfill,babel,angular,reactJS,vueJS 等众多框架。但是归根结底JavaScript是一种同步编程语言。

但是由于具备非阻塞和回调机制,JavaScript也可以实现异步功能。而根据MDN上对于Promise机制的描述(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise),Promise对象是一个代理对象(代理一个值),被代理的值在Promise对象创建时可能是未知的。它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的promise对象。示例及注释如下:

综上笔者认为可以将Promise理解成Java中的Callback,用以帮助JavaScript实现异步功能。

而本次出现问题的is-promise包,就是用来测试一个JavaScript对象是否为Promise的。is-promise包的代码其实非常短,其主要的功能实现代码只有两行而已。前端开发人员在引入is-promise包之后,就能在自己的项目中引用它,而且is-promise包是基于MIT协议的,因此引用该项目,也不必须要求开源。虽然只有两行代码,但is-promise 库却是当今最受欢迎的 JavaScript 软件包之一。据不完全核计is-promise是700余个知名的JavaScript 库的依赖项,其影响项目数量至少超过300万,范围涵盖至封闭源 JavaScript 代码库和 JavaScript 生态系统中一些最大的项目。其中包括有:Facebook 的 Create React App(用于创建 React 应用程序的标准模板)、谷歌的 Angular.js 框架、谷歌的 Firebasse-tools、亚马逊的 AWS Serverless CLI、Nuxt.js 和 AVA 等。

引发问题的ES 模块标准

 is-promise 库之所以引发问题,关键在于他没有遵循正确的ES模块标准,而提到ES模块标准,我们还要从最基本的概念聊起。我们知道JavaScript是一门动态的脚本化的语言,它使得前端页面的开发变得非常简单。

JavaScript的编程范式抽象成维护变量,赋值和计算操作。大量的代码在用于操作变量,开发者需要懂得如何去组织和维护这些变量。JavaScript 提供了一种方式,即函数作用域。在一个函数内只需要考虑这个函数的变量问题。不必去担心其他函数会操作这些变量。当然,随之带来的问题是,变量无法共享,无法在不同的函数之间相互共享变量。如  果想要在作用域外共享变量,只能通过外层作用域,或者全局作用域。

而ES模块标准,则提供了更好的方式来组织变量和函数,把相关的变量和函数组织到一起。具体就是将这些函数和变量放到一个模块作用域内,实现在模块间共享变量。与函数作用域不同的是,模块内部的变量实现了在其他模块内共享。而且可以指定哪些变量、类或者函数可以共享。在其他模块中共享,被称为 export。这就出现了模块间的依赖,是一种很明确的关系,当移除一个模块时可以准确的知道哪些模块会出错。一旦有了模块间导出和引用变量的能力,我们就可以将代码打成小包。然后就可以像乐高玩具那样组合,再组合。使用小模块就可以创建出各类应用。在使用模块的时候,其实就是在做一个依赖关系图。ESM的模块包括三个过程:

1:构建:下载,解析,然后把文件解析为模块记录

2:实例化:为模块分内存空间(此时还没赋值),然后依照导入,导出语句把模块指向内存地址,这个过程叫链接

3:运行(求值):运行代码的时候,才会给内存空间填充真实的值

而ES则通过一系列的标准来确保相关代码可以实现上述模块化的功能。

is-promise v.2.2.0 版本却未遵循正确的 ES 模块标准。因此在其更新发布后,引用了is-promise在各个项目都在的构建链时出现了问题。

总结一下本文内容Promise是Javascript中实现异步功能的重要机制,is-promise又是目前流行度最高的promise对象检测工具,而由于is-promise没有遵循正确的ES模块标准,使得其它引用了promise包的程序出现了问题。

最后笔者还是引用司徒正美老师生前名言做结。当初JavaScript被误解为最糟糕的语言,时至今日它是最流行的语言,GitHub 60%的项目都是与JavaScript有关。任何可以使用JavaScript来编写的应用,最终会由JavaScript编写。愿前端开发之路越来越好!

两行代码引发的血案-代笔司徒老师相关推荐

  1. 研发效能度量:破解千行代码缺陷率引发的“血案”

    本文共计2500字,建议阅读时间:5~6分钟. ‍ 阅读本文你将收获: 1.搞清楚度量的概念和分类 2.用系统化破解"血案" 3.研发效能度量的系统方法 ‍ 前言:人们常常认为软件 ...

  2. silverlight Image Source URI : 一个反斜杠引发的血案

    silverlight Image Source URI : 一个反斜杠引发的血案 Silverlight2 现在支持的Image格式有jpg和png,部分png编码也不支持,同时有些png在xaml ...

  3. 转:一个Sqrt函数引发的血案

    转自:http://www.cnblogs.com/pkuoliver/archive/2010/10/06/1844725.html 源码下载地址:http://diducoder.com/sotr ...

  4. 一个Sqrt函数引发的血案

    我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢? 虽然 ...

  5. 1135 mysql_Mysql实例mysql中一个普通ERROR 1135 (HY000)错误引发的血案

    <Mysql实例mysql中一个普通ERROR 1135 (HY000)错误引发的血案>要点: 本文介绍了Mysql实例mysql中一个普通ERROR 1135 (HY000)错误引发的血 ...

  6. 从TdEngine20行代码引发的风波,看10倍程序员与普通程序员的差距

    上周笔者的一篇博客这位创造Github冠军项目的老男人,堪称10倍程序员本尊对于TdEngine的建立过程及其创始人陶建辉老师进行了介绍,并对于TdEngine团队在github上开源的一段consu ...

  7. 只需两行代码,2080Ti 就能当 V100用,这个炼丹神器真牛!

    作者 | 陈大鑫.青暮 话说人工智能江湖门派众多且繁杂,好似那大脑中的神经网络一般,但繁杂中却仍然有着一统的迹象...... 许久之前,ML派坐落美利坚合众山中,百年来武学奇才辈出,隐然成江湖第一大名 ...

  8. mysql backlog_一次优化引发的血案

    前些天一个Nginx+PHP项目上线后遭遇了性能问题,于是打算练练手,因为代码并不是我亲自写的,所以决定从系统层面入手看看能否做一些粗线条的优化. 首先,我发现服务的Backlog设置过小,可以通过s ...

  9. 一个普通ERROR 1135 (HY000)错误引发的血案:

    一个普通ERROR 1135 (HY000)错误引发的血案: 今天接到测试人员反应,测试环境前端应用程序无连接mysql数据库,登录mysql服务器,查看错误日志,发现有如下报错: 点击(此处)折叠或 ...

最新文章

  1. 3d模型 vv5_WEY VV5硬刚现代ix35!神仙颜值种草95后小伙
  2. 通过 Feature Level 动态控制 SAP Spartacus 的页面显示
  3. 面向对象笔试题练习一
  4. windows10 安装mqtt服务器和client客户端进行本地调试
  5. 消息长度_填坑笔记:RocketMQ消息订阅失败问题?
  6. 在控制台输出九九乘法表
  7. 麦子mysql_[数据库]MySQL基础 (麦子学员 php 第二阶段)
  8. Wannafly挑战赛23 A 字符串
  9. 一个@Transaction哪里来这么多坑?
  10. IMAX影厅专候天神下凡 巨幕电影2010年观影指南
  11. 阿拉伯数字转换成中文大写
  12. python正则怎么取反_第11.19节 Python 中正则表达式的扩展功能:前视断言和前视取反...
  13. 请君入瓮:研究员找到 Emotet 的bug,并成功阻止传播
  14. vue中组件间的传参
  15. SpringCloud知识点复习(第一次)
  16. java中412是什么错_412错误是什么 412错误怎么解决
  17. MAC删除开机自启动程序
  18. 三十八、西梁女儿国疑案之一落胎泉的秘密
  19. WPS自定义样式功能太弱了
  20. 智慧零售企业向服务升级进行时,全面实时监控成重点

热门文章

  1. 操作系统与Linux
  2. ROOT(a Data analysis Framework)-Note6: iSTEP day3-Random
  3. docker容器4:docker网络类型+跨主机访问
  4. mac系统计算机名,苹果电脑系统各版本名字该怎么念?
  5. 软件著作权登记证书可以加分落户评职称评人才,不少大学不少地方把软著列入加分项,办理软件著作权需要什么流程?
  6. 视频聊天网站的技术与发展
  7. Python之三元运算、集合、函数
  8. Windows PowerShell 中启动 Nginx 报错解决方案
  9. linux下的磁盘常用工具
  10. 【Android】Android中如何取消调转界面后EditText默认获取聚焦问题