『JavaScript』两行代码的库引发“血案”:坑了数百万个项目


『JavaScript』两行代码的库引发“血案”:坑了数百万个项目
本文插图
作者 | 马超
责编 | 伍杏玲
出品 | 程序人生(ID:coder_life)
4月25日 , 一个体量很小的 JavaScript 库is-promise 进行了更新 。
由于最新版本没有遵循正确的 ES 模块标准 , 使得超过300万个引用了is-promise的前端项目均出现了问题 , 这个问题甚至让整个 JavaScript 生态系统陷入了混乱 。 由于前端项目的构造方式与中后台项目的机制不同 , 这种由小型 JavaScript 项目引起广泛问题的情况已经不是第一次发生了 。 这次的问题并没有导致现有 JS 项目崩溃 , 主要问题是无法编译新版本 。
当笔者看到这个新闻 , 心中不由得一颤 , 因为司徒正美老师生前一直奋斗的前端技术领域 , 当我来写这篇文章时 , 执笔当哭 , 缅怀旧人 。
笔者和司徒结识于CSDN , 记得是去年6月 , 当时我看到一篇博文《前端开发 20 年变迁史》 , 心中不由赞叹 , 竟有人能将前端技术上升到哲学高度来进行阐释 , 于是千方百计地找到了司徒的微信加为好友 , 和司徒聊天中 , 明显能感受到他对于前端技术的理解深度和积极热情 。 谁知天有不测风云 , 司徒年纪轻轻竟然溘然长逝 , 在此笔者也提示各位读者朋友们保重身份 , 切莫透支健康 。
下面笔者帮助大家解读一下这则新闻背后的技术细节 。 由于前端并不是笔者的领域 , 如有错漏还请各位指正 。
『JavaScript』两行代码的库引发“血案”:坑了数百万个项目
本文插图
初识promise
因为笔者对于JavaScript也不是特别了解 , 在初步学习后我看到了阻塞代码、非阻塞代码、事件驱动设计模式、事件生命周期、函数堆栈、事件队列等概念 , 以及polyfill、babel、angular、reactJS、Vue.JS 等框架 。
JavaScript是单线程执行代码 , 但是由于具备非阻塞和回调机制 , JavaScript也可以实现异步功能 。 于是有了Promise机制 。
根据MDN上对于Promise机制的描述(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise):Promise对象是一个代理对象(代理一个值) , 被代理的值在Promise对象创建时可能是未知的 。 它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers) 。 这让异步方法可以像同步方法那样返回值 , 但并不是立即返回最终执行结果 , 而是一个能代表未来出现的结果的promise对象 。
示例及注释如下:
//创建一个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]
综上笔者认为可以将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 生态系统中一些最大的项目 。