iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > node.js >怎么理解Promise中的core.js
  • 786
分享到

怎么理解Promise中的core.js

2024-04-02 19:04:59 786人浏览 八月长安
摘要

这篇文章主要讲解了“怎么理解Promise中的core.js”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Promise中的core.js”吧!源码

这篇文章主要讲解了“怎么理解Promise中的core.js”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Promise中的core.js”吧!

源码阅读阶段

先理解Promise根本吧,想快点理解的话可以直接跳到下个标题.这部分根据理解将持续修改。

Promise(fn)

function noop() {}  var LAST_ERROR = null;//记录Promise内部***的一次错误 var IS_ERROR = {}; //空对象,标识表示发生了错误 module.exports = Promise; //暴露模块接口为Promise function Promise(fn) {   if (typeof this !== 'object') {     throw new TypeError('Promises must be constructed via new');   }   if (typeof fn !== 'function') {     throw new TypeError('Promise constructor\'s argument is not a function');   }   this._deferredState = 0;   this._state = 0; //promise状态   this._value = null; //resolve返回的结果   this._deferreds = null;   if (fn === noop) return;   doResolve(fn, this); //处理函数 } Promise._onHandle = null; Promise._onReject = null; Promise._noop = noop;

原文中表示将带有_前缀的变量在构造的时候转为(_随机数)的形式,来混淆和阻止它们被使用.接下来列出说明重要的变量。

* _defferedState = 0 表示_deferreds的类型,0时表示null,1时表示单个handler(后面讲述),2表示多个deferreds(数组) * _state = 0 promise状态,0为pending,1为fulfilled,2为rejected,3则为值已被传递给下个promise. * _value = null resolve返回的结果,也就是我们所说的终值/拒因 * _deferreds = null 表示单个或多个handler(后面讲述)

doResolve(fn,this)

相比大家都看到这行函数了doResolve(fn,  this);,这里也就是我们初始化一个Promise时会做的事了,我们在看这个函数前,先理解下源码中类似于工具函数一样的函数。

//获取then方法,没有then方法标识错误 function getThen(obj) {   try {     return obj.then;   } catch (ex) {     LAST_ERROR = ex;     return IS_ERROR;   } } //内部捕获错误,单个参数函数 function tryCallOne(fn, a) {   try {     return fn(a);   } catch (ex) {     LAST_ERROR = ex;     return IS_ERROR;   } } //内部捕获错误,两个参数函数 function tryCallTwo(fn, a, b) {   try {     fn(a, b);   } catch (ex) {     LAST_ERROR = ex;     return IS_ERROR;   } }

接下来我们直接跳到doResolve(fn,promise)处:

function doResolve(fn, promise) {//传入参数为一个函数,一个promise对象   var done = false; //保证了规范中提到的一次性   var res = tryCallTwo(fn, function (value) {//看到了么,用于捕获错误.     if (done) return; //这里不用说了,为了保证两个函数中只有一个函数运行且仅运行一次     done = true;     resolve(promise, value);//后续再分析它   }, function (reason) {     if (done) return;     done = true;     reject(promise, reason);//后续再分析它   });   if (!done && res === IS_ERROR) {     done = true;     reject(promise, LAST_ERROR);//后续再分析它   } }

这就是我们的doResolve函数,可以看出,它只是个中间件,用于干什么的呢,就是解决传入函数error问题并进行reject的.重点是调用了我们很眼熟的两个函数,resolve()和reject()。

resolve() and reject()

在这个函数里我们找到了两个新东西,resolve()和reject(),看名字就知道这两个函数是什么啦,我们先看reject()吧!

function reject(self, newValue) {//两个参数,从doResolve我们可以知道self是一个promise对象,而newValue就是拒因啦   self._state = 2;//状态变成rejected了   self._value = newValue;//promise中结果变为拒因   if (Promise._onReject) {//在core.js中它为null,所以可能是用于别的功能.我们直接跳过     Promise._onReject(self, newValue);   }   finale(self);//新的函数又出现了. }

reject()函数传入了promise对象和一个reason拒因,函数做的就是将promise的状态变为rejected,并将promise的值进行更改.然后调用finale()函数。

可以看到出现了新函数finale(),并且传了已经进行完reject的promise对象给它.但是我们还是先看resolve()吧!

function resolve(self, newValue) { //这里写的其实就是按照规范处理的流程      if (newValue === self) {//传入值等于自己就抛出错误     return reject(       self,       new TypeError('A promise cannot be resolved with itself.')     );   }   if (//值为对象或函数     newValue &&     (typeof newValue === 'object' || typeof newValue === 'function')   ) {     var then = getThen(newValue);//获取值中的then函数     if (then === IS_ERROR) {//不存在then,reject去       return reject(self, LAST_ERROR);     }     if (//存在并且原来值它是一个promise对象       then === self.then &&       newValue instanceof Promise     ) {//同步两个promise,将传入的promise状态变为已传递并把newValue这个promise对象作为promise的值,然后finale并退出函数.       self._state = 3;       self._value = newValue;       finale(self);       return;     } else if (typeof then === 'function') {//如果获取到then的值不为promise,但then是一个函数(thenable)       doResolve(then.bind(newValue), self);//这里可以看看上个博文,对这个情况有说明,对终值自身进行doResolve取得新的值作为新的终值.       return;     }   }   self._state = 1;//promise状态为fulfilled   self._value = newValue;//值传递   finale(self);//finale了 }

在resolve()中,我们照样是传进了一个promise对象和value(终值),函数内部通过标准的判断(详细参考学习笔记(二):规范),进行[[Resolve]]操作,***将promise对象状态变更为fulfilled并改变其终值,调用finale。

finale()

我们可以进行finale()的分析了,毕竟我们的核心函数都指向它呢!

function finale(self) {//传入了一个promise对象   if (self._deferredState === 1) {//判断deferreds是单个     handle(self, self._deferreds);//传入了promise对象和promise对象中的_deferreds     self._deferreds = null;//让deferreds为null   }   if (self._deferredState === 2) {//判断deferreds是数组     for (var i = 0; i < self._deferreds.length; i++) {       handle(self, self._deferreds[i]);//传入了promise对象和promise对象中的_deferreds数组的所有数据     }     self._deferreds = null;//让deferreds为null   } }

很好,这下都是新的东西了,_deferredState这个就是判断_deferreds是数组还是单个的情况,并对其中每一个deferred进行handle调用.但是_defferreds又是什么呢,handle()这个函数又做了什么处理呢...

handle()

function handle(self, deferred) {//这个传入参数是预想之中的   while (self._state === 3) {//promise状态为3的时候,也就是该promise已传递完毕的时候     self = self._value;//重定位self为promise传递的值   }   if (Promise._onHandle) {//同样不属于本篇考虑范畴     Promise._onHandle(self);   }   if (self._state === 0) {//promise状态为pending时     if (self._deferredState === 0) {//没有deferreds时       self._deferredState = 1;//deferreds变为单个       self._deferreds = deferred;传入deferreds入列       return;     }     if (self._deferredState === 1) {       self._deferredState = 2;//deferreds变为数组       self._deferreds = [self._deferreds, deferred];//传入deferred进入数组       return;     }     self._deferreds.push(deferred);//已经是数组了就直接push增加     return;   }   handleResolved(self, deferred);//新东西,在state!==0时传入promise和defered }

可以看到其实这个函数在对_deferreds进行添加,进行着_deferreds的修改和写入,与finale()所做的事情恰恰相反,但是详细的处理却还是在handleResolved()函数里面。

handleResolved()

function handleResolved(self, deferred) {   asap(function() {//注意!asap是一个引入的模块,意思就是as soon as possible,就是尽快执行的意思,我们不需要考虑它做了什么.     // promise状态是fulfilled情况下cb为deferred中的Fulfilled函数,不是的话则为onRejected函数...     var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;     if (cb === null) {//如果不存在对应状态的函数       if (self._state === 1) {//当前promise对象是否为fulfilled状态         resolve(deferred.promise, self._value);//传入deferred中保存的promise和当前promise的值进行resolve       } else {         reject(deferred.promise, self._value);//与上类似,进行reject       }       return;     }     var ret = tryCallOne(cb, self._value);//存在则尝试执行对应函数,返回执行结果(与两个参数的tryCall不同,这里返回了函数运行结果)     if (ret === IS_ERROR) {//有错误,reject       reject(deferred.promise, LAST_ERROR);     } else {//没错误,对deferred.promise用函数返回值进行resolve       resolve(deferred.promise, ret);     }   }); }

这里我们看到了deferred是一个保存了promise对象,onFulfilled函数,onRejected函数的对象,相当于一个保存现场.其实这里就是我们即将在源码core.js解析(下)写到的handler对象了.但是这里我们暂且先不深究,知道就好了。

handleResolved()毫无疑问就是在进行着promise的终值传递处理,对旧promise对象的状态修改,并调用resolve和reject获取到值/拒因向下一个Promise传递.对这里的详细实例分析我们放到(下)来讲。

构造一个Promise时发生了啥?

从简单看起,我们构造一个Promise对象的时候经过了哪些函数。

先理一下思路。

var A = Promise(function(resolve,reject){     resolve("ok"); })

这里面首先是先构造了Promise对象,我们称为A,在构造阶段执行了如下代码。

检查略....

A._deferredState = 0; A._state = 0; A._value = null; A._deferreds = null;

检查传入参数不为空....

doResolve(function(resolve,reject){     resolve("ok"); },this);

然后我们跳到了doResolve()函数处,传入为fn,promise

res = tryCallTwo(fn,function(value){resolve(promise, value);},function(reason){reject(promise, reason);}); 出错就reject(promise,LAST_ERROR)

出错就reject(promise,LAST_ERROR)

我们又根据我们的输入跳转到了resolve(promise,value)啦,这里理一下我们的函数,promise就是A,value其实就是我们传入的"ok"。

所以执行的是promise内部中的resolve(promise,"ok")

经过一系列判断(详细可以看规范),我们的"ok"过五关斩六将直接执行到这一步。

self._state = 1;//A状态变为fulfilled self._value = newValue;//AA终值变为"ok"

然后我们finale(self)啦,继续跳到finale()函数,传入了A.

//在过程中我们的_deferredState始终为0呀,看了一下 A._deferredState = 0; //已经没有什么好做的了...

感谢各位的阅读,以上就是“怎么理解Promise中的core.js”的内容了,经过本文的学习后,相信大家对怎么理解Promise中的core.js这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 怎么理解Promise中的core.js

本文链接: https://www.lsjlt.com/news/86305.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么理解Promise中的core.js
    这篇文章主要讲解了“怎么理解Promise中的core.js”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解Promise中的core.js”吧!源码...
    99+
    2024-04-02
  • 怎么理解ES6 Promise对象
    这篇文章主要讲解了“怎么理解ES6 Promise对象”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解ES6 Promise对象”吧!概述是异步编程的...
    99+
    2024-04-02
  • 如何理解JavaScript中的Promise
    如何理解JavaScript中的Promise,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。pr...
    99+
    2024-04-02
  • JavaScript中的Promise详解
    目录Promise的基本用法:1、创建Promise对象2、Promise 方法总结Promise是异步编程的一种解决方案,是一个对象,可以获取异步操作的消息,大大改善了异步编程的困...
    99+
    2024-04-02
  • 怎么弄懂Promise原理
    这篇文章主要介绍“怎么弄懂Promise原理”,在日常操作中,相信很多人在怎么弄懂Promise原理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么弄懂Promise原理”...
    99+
    2024-04-02
  • JavaScript中Promise怎么用
    这篇文章主要为大家展示了“JavaScript中Promise怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JavaScript中Promise怎么用”这...
    99+
    2024-04-02
  • javascript中的Promise怎么使用
    这篇“javascript中的Promise怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“javascript中的P...
    99+
    2023-06-30
  • javascript中Promise原理是什么
    本篇内容主要讲解“javascript中Promise原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“javascript中Promise原理是什么”吧...
    99+
    2024-04-02
  • ES6中Promise怎么用
    这篇文章主要为大家展示了“ES6中Promise怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ES6中Promise怎么用”这篇文章吧。Promise 基...
    99+
    2024-04-02
  • es6中promise怎么使用
    这篇文章主要介绍了es6中promise怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇es6中promise怎么使用文章都会有所收获,下面我们一起来看看吧。es6 promise用于异步编程。Promi...
    99+
    2023-07-04
  • ES6的Promise怎么用
    这篇文章主要为大家展示了“ES6的Promise怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“ES6的Promise怎么用”这篇文章吧。什么是PromisePromise 是异步编程的一种...
    99+
    2023-06-22
  • JavsScript中Promise的错误捕获问题怎么解决
    本篇内容介绍了“JavsScript中Promise的错误捕获问题怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!我们需要在异步任务中...
    99+
    2023-07-02
  • JavaScript中Promise的简单使用及其原理详解
    Promise是ES6最重要的特性之一,今天来系统且细致的研究一下Promise的用法以及原理。 按照我往常的理解,Promise是一个构造函数,有all、resolve、rejec...
    99+
    2023-03-23
    JavaScript Promise原理 JavaScript Promise使用 JavaScript Promise
  • es6的promise怎么使用
    今天小编给大家分享一下es6的promise怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2024-04-02
  • 怎么写出符合Promise/A+ 规范Promise的源码
    这篇文章主要介绍“怎么写出符合Promise/A+ 规范Promise的源码”,在日常操作中,相信很多人在怎么写出符合Promise/A+ 规范Promise的源码问题上存在疑惑,小编查阅了各式资料,整理出...
    99+
    2024-04-02
  • ES6中怎么使用Promise对象
    这期内容当中小编将会给大家带来有关ES6中怎么使用Promise对象,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在promise之前处理异步回调的方式function&...
    99+
    2024-04-02
  • js中关于promise怎么使用
    这篇文章主要介绍“js中关于promise怎么使用”,在日常操作中,相信很多人在js中关于promise怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”js中关于promise怎么使用”的疑惑有所帮助!...
    99+
    2023-07-05
  • JavaScript中Promise的执行顺序详解
    目录前言代码分析then 方法何时调用?总结前言 最近看到一个 Promise 相关的很有意思的代码: new Promise((resolve) => { console...
    99+
    2024-04-02
  • JavsScript中Promise的错误捕获详解
    目录我们需要在异步任务中准确的进行错误捕获,以便我们可以知道错误出在什么地方我们再讨论then方法中的第二个参数和Promise.catch方法的区别题: then方法的连续调用,怎...
    99+
    2024-04-02
  • JavaScript中Promise的原理是什么及如何使用
    这篇文章主要介绍了JavaScript中Promise的原理是什么及如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript中Promise的原理是什么及如何使用文章都会有所收获,下面我们一起...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作