Promise
【JS进阶】Javascript 闭包与Promise的碰撞
最近遇到一个比较有意思的题目,解决之后深入地思考了一下。 整理整理我在其中的收获,写个文章分享给大家。 一等公民进入正题之前再聊聊一个话题 —— JavaScript 的一等公民 在 JavaScript 这门语言中,一等公民不仅包含了 变量,对象 等这些名词性的语法,更重要的是 函数 也是一等公民!因此: 函数也可以被当做参数来传递函数也可以作为函数的返回值函数也可以被赋值到某个变量函数也动态地先定义(赋值到某个变量)再执行…
路过,爪机敲点 不需要这俩,这俩是 JS 范围内的。 fs 是 c++ 层面的,异步实现是个 io 线程池。 由于c++层面给的读写文件 api 是同步的。要想同步就当前线程里直接调用拿结果。要想异步就是扔线程里自己跑去,新线程里读写文件这个操作完事了或者某个阶段目标到了通知原始线程。 所以,node 里 sync 的就是直接调读写的。async 的往 io 线程池里扔,确保当前线程不卡。 和你说的这俩没关系。
我把整个过程详细分解说一下,同学们就明白了。 接下来的阅读注意两点:一是不要被网上流行的一些帮助初学者快速了解的不严密说法先入为主,跳不出误区。二是不要混淆两个 resolve,即 Promise.resolve (全局对象 Promise(它当然也是构造子)的属性 resolve 函数对象)和 new Promise((resolve, reject)=>...) 里的 resolve(其实质是规范中的 Promise Resolve Function,链接在文末。)。(then 创建新 Promise 实例,其中一…
这两天刚好在某个JavaScript引擎中实现并测试好了async/await语法,底层实现肯定是围绕着Promise实现的,但一般来说并不是也没有必要在(C语言或C++语言层面)底层,搞一套模拟generator行为来实现async/await语法,底层有更加简单直接的方法。 经过测试async/await语法是可以正常使用的: [图片] async函数底层实现:async函数行为很简单,就是看函数的返回值是否为Promise,如果不是Promise,则用resolve转成Promise。 await语法会去…
路过 肯定泄漏 因为不管如何,没有resolve也没有reject,在 microtask 中待 TryRunMicrotasks 的代码就不会被执行,jobqueues 内必然会有残留内容。这些内容在引擎层不可能会预知到何时被调用(特别是上游host包装的调用,作为下游的引擎层肯定无法预知),必须要保留内容,不会被GC干掉。 如果有 resolve 过,但是这个 resolve 还在其它地方被持有,比如某个一直未被调用的方法。这时虽然 jobqueues 内该任务被执行过,被移除,…
路过…… 撸了下规范,等撸懂了,扫听下各种答案发现 @李杭帆 已经答挺好了……这里就简化下描述吧…… 实际从规范来说, 是 Promise Resolve Functions 步骤中 FulfillPromise > TriggerPromiseReactions > NewPromiseReactionJob > HostEnqueuePromiseJob 和 NewPromiseResolveThenableJob > HostEnqueuePromiseJob导致的区别 可以看到,前者是 return 俗称的 "非 promise 对象" 情况下处理过程,入队的是 NewPromiseReactionJ…
WHY “PROMISES ARE NOT NEUTRAL ENOUGH” IS NOT NEUTRAL ENOUGH
这篇文章的标题有点绕口,不过大家都懂的,这是一个吐槽手法。 本文就是要吐槽 Staltz 最近写的这篇文章《 Promises are not neutral enough 》。 Staltz 作为 Cycle.js 的作者,也算是社区名人之一。最近他搞了一个大新闻叫 Callbag( Why we need Callbags ),一看名字就是给 callback 招魂的。这篇我不打算吐槽 callbag(想看吐槽 callbag 的可移步:callbag和rxjs有什么区别? ),就单吐槽一下 Staltz 对于 promise 的偏见。S…
[图片] 一.源码V8 版本 8.4.371,本题的难点在于 resolve 的参数为 Promise 对象。 记第一行 new Promise 生成的 Promise 为 p0。 执行第 2 行 let resolvedPromise = Promise.resolve() 后,resolvedPromise 是一个 fulfilled 状态的 Promise,此时 microtask 队列为空。 执行第 3 行 resolve(resolvedPromise),调用 V8 的 ResolvePromise ,源码如下:// https://tc39.es/ecma262/#sec-promise-resolve-functions transitioning built…
猜一猜为什么 vscode 的源码里重新造了 CancellationTokenSource、CancellationToken 等一大堆设施?其实就是为了弥补 Promise 不能取消的缺陷。不然你想象一下你编写代码时按下了一个 .,此时 vscode 向后台的语言服务发异步请求来获取符号信息和补全列表,但是你打的很快,立马又输入了好几个字符,此时如果不把前面的请求取消掉,难道等着后台语言服务一遍又一遍地查找符号吗?再比如点击一个“跳转到定义”,然后突然不想看…
结论:调用 then 方法时 Promise 状态为 fulfilled,回调函数 onFulfilled 直接加入 microtask 队列;调用 then 方法时 Promise 状态为 pending,首先将 onFulfilled 加入一个链表,待 Promise 状态变为 fulfilled 后,将链表中的每一项加入 microtask 队列。 V8 版本 8.4,then 函数最终会调用 PerformPromiseThenImpl ,只保留和本题相关的源码如下:transitioning macro PerformPromiseThenImpl(implicit context: Context)( p…
Promise is an implementation of PromiseLike 我查了一下TypeScript的文档,确实没有明面上写明PromiseLike.但我在源码生成的文档中找到了它。 PromiseLike | typescript - v3.7.7 (microsoft.github.io) 在TypeScript中 PromiseLike 是以Interface 定义的接口类型。它需要实现thenable 特征。其中 then 之函数的签名如下:then( onfulfilled?: function | undefined | null, onrejected?: function | undef…
先回答这三个问题。 1. Promises/A+ 的规范制定目前看没什么漏洞。这个规范本质上就是一个需求文档,只要实现满足需求文档的需求就算是合格的实现。对于需求来说,不存在漏洞。 2. Promise规范和微任务没任何的关系。 至少从Promise规范诞生的历史来看是如此。 3. 从工程师的角度说,死磕 Promise 执行顺序的面试题,就是吹毛求疵。这是大厂面试硬卷出来的结果。就跟早年国外大厂面试只要死命卷算法就能行一个道理。专门为了回答…
1.什么是 Promisepromise 是目前 js 异步编程的主流解决方案,遵循 Promises/A+ 方案。 2.原理简析(1)promise 本身相当于一个状态机,拥有三种状态 pendingfulfilledrejected 一个 promise 对象初始化时的状态是 pending,调用了 resolve 后会将 promise 的状态扭转为 fulfilled,调用 reject 后会将 promise 的状态扭转为 rejected,这两种扭转一旦发生便不能再扭转该 promise 到其他状态。(2)promise 对象原型上有一个 the…
前言 本周写文的核心为 Promise ,Promise 大家应该都特别熟悉了,Promise 是异步编程的一种解决方案,广泛用在日常编程中。本周小包将围绕 Promise 源码手写进行写文,源码手写初步计划使用三篇文章实现—— 手写 Promise 之基础篇,手写 Promise 之 resolvePromise 篇,手写 Promise 之静态方法篇。 Promises/A+ 规范是 Promise 的实现准则,因此 Promise 手写系列将遵循 Promises/A+ 规范的思路,以案例和提问方式层层深入,…
用 babel 编译成了 promise,这样看应该比较清晰一些,不一定和浏览器原生的实现一致,但也能大概说明问题了。 function p1() { return Promise.resolve().then(function () { return 1; }); } function p2() { return Promise.resolve().then(function () { return Promise.resolve(2); }); } p2().then(res => { console.log(res); // 输出 2 }); p1().then(res => { console.log(res); // 输出 1 });
其实也不用纠结,只需要知道 PromiseLike是一个「鸭子类型(Duck Typing)」就可以了。一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由“当前方法和属性的集合”决定。当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。 长得像 Promise,那它就是Promise,怎么才叫做像呢?有then方法可调用就行。主要是原生 JS 中没有给出类似 isArray一样的isPromise方法,只能取一…
不是,一个是微任务,一个是宏任务。这篇翻译文章可能会更好的解释这个问题。 更多内容,欢迎关注我的公众号:dingtingli-pub点击访问: 原文地址 作者: Lydia Hallie 你是否遇到过 JavaScript 代码没有按照你预期的方式来运行?看起来就好像是函数在随机、不可预测的时间被执行,或者是被延迟执行。这时候,你可能是在处理 ES6 中的新特性: Promises。 多年之前的好奇心终于有了回报,在又一次的不眠之夜中我终于有时间做了一些…
不知道大家读中学的时候有没有见过这种老师——当他发现参考答案是A的时候,他能找出100个理由解释A;当他发现诶看错了,其实答案是B的时候,他马上又能找出100个理由解释B。 本题下的高票答主如果当老师的话,都会是这种神棍老师。一个个解释得头头是道,殊不知Haskell 里就实现了。 js中promise的数学模型是一个either函子和future函子的复合。haskell中async的数学模型也是一个either函子和future函子的复合。js中promise的语…
带着问题读代码比较有意思,试着搜索一下v8代码。 首先,resolve的时候,micro task的创建是在resolve之后new的,所以,如果没有resolve,则没有额外的引用, [图片] 整个过程太多,贴不过来,大意是当resolve调用时,这个resolve可以查找到原来new的promise(我以前写过,Promise::Resolver引用Promise,resolve可以直接找到原来的Promise),之后根据Promise的一些信息创建调用需要的各种环境,然后在贴图代码位置创建Micro task。 那…