Promise then中回调为什么是异步执行?Promise执行机制问题
今天发现一个问题,看下方代码
let p = new Promise(function(resolve, reject) {
resolve()
console.log('');
});
p.then(res => {
console.log('');
})
输出结果是2222 1111,而自己想的是1111 2222,带着问题查询之后发现.
原来then后边跟的都是异步执行..学习到了.
此链接是各位大佬的回答https://www.zhihu.com/question/57071244
用网上学习ES5实现的Promise ,输出结果和自己想的一样,原因可以去上方地址找到.
下方是ES5实现的promise
function Promise(callback) {
var self = this;
self.status = 'PENDING'; // Promise当前的状态
self.data = undefined; // Promise的值
self.onResolvedCallback = []; // Promise resolve时的回调函数集
self.onRejectedCallback = []; // Promise reject时的回调函数集
callback(resolve, reject); // 执行executor并传入相应的参数 function resolve(value) {
if (self.status == 'PENDING') {
self.status == 'FULFILLED';
self.data = value;
// 依次执行成功之后的函数栈
for (var i = 0; i < self.onResolvedCallback.length; i++) {
self.onResolvedCallback[i](value);
}
}
} function reject(error) {
if (self.status === 'PENDING') {
self.status = 'REJECTED';
self.data = error;
// 依次执行失败之后的函数栈
for (var i = 0; i < self.onRejectedCallback.length; i++) {
self.onRejectedCallback[i](error);
}
}
}
} Promise.prototype.then = function(onResolved, onRejected) {
var self = this;
var promise2; // 根据标准,如果then的参数不是function,则我们需要忽略它,此处以如下方式处理
onResolved = typeof onResolved === 'function' ? onResolved : function(value) {};
onRejected = typeof onRejected === 'function' ? onRejected : function(reason) {}; if (self.status === 'FULFILLED') {
// 如果promise1(此处即为this/self)的状态已经确定并且是resolved,我们调用onResolved
// 因为考虑到有可能throw,所以我们将其包在try/catch块里
return (promise2 = new Promise(function(resolve, reject) {
try {
var x = onResolved(self.data);
if (x instanceof Promise) {
// 如果onResolved的返回值是一个Promise对象,直接取它的结果做为promise2的结果
x.then(resolve, reject);
}
resolve(x); // 否则,以它的返回值做为promise2的结果
} catch (e) {
reject(e); // 如果出错,以捕获到的错误做为promise2的结果
}
}));
} // 此处与前一个if块的逻辑几乎相同,区别在于所调用的是onRejected函数,就不再做过多解释
if (self.status === 'REJECTED') {
return (promise2 = new Promise(function(resolve, reject) {
try {
var x = onRejected(self.data);
if (x instanceof Promise) {
x.then(resolve, reject);
}
} catch (e) {
reject(e);
}
}));
} if (self.status === 'PENDING') {
// 如果当前的Promise还处于pending状态,我们并不能确定调用onResolved还是onRejected,
// 只能等到Promise的状态确定后,才能确实如何处理。
// 所以我们需要把我们的**两种情况**的处理逻辑做为callback放入promise1(此处即this/self)的回调数组里
// 逻辑本身跟第一个if块内的几乎一致,此处不做过多解释
return (promise2 = new Promise(function(resolve, reject) {
self.onResolvedCallback.push(function(value) {
try {
var x = onResolved(self.data);
if (x instanceof Promise) {
x.then(resolve, reject);
}
resolve(x); // 否则,以它的返回值做为promise2的结果
} catch (e) {
reject(e);
}
}); self.onRejectedCallback.push(function(reason) {
try {
var x = onRejected(self.data);
if (x instanceof Promise) {
x.then(resolve, reject);
}
} catch (e) {
reject(e);
}
});
}));
}
}; // 为了下文方便,我们顺便实现一个catch方法
Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
Promise then中回调为什么是异步执行?Promise执行机制问题的更多相关文章
- promise、async、await、settimeout异步原理与执行顺序
一道经典的前端笔试题,你能一眼写出他们的执行结果吗? async function async1() { console.log("async1 start"); await as ...
- 简单而面试中又常见的知识点:JS执行机制
在开始讲解之前,我们先来看一段代码: console.log('1'); setTimeout(function() { console.log('2'); process.nextTick( ...
- ES6(promise)_解决回调地狱初体验
一.前言 通过这个例子对promise解决回调地狱问题有一个初步理解. 二.主要内容 1.回调地狱:如下图所示,一个回调函数里面嵌套一个回调函数,这样的代码可读性较低也比较恶心 2.下面用一个简单的例 ...
- when 让你跳出异步回调噩梦 node.js下promise/A规范的使用
其实关于promise 的博客,前端时间专门写了一篇关于 promise 规范的文章,promise规范 让 javascript 中的异步调用更加人性化. 简单回忆下: promise/A规范定义的 ...
- $.getJSON('url',function(data){}) 中回调函数不执行
$.getJSON('url',function(data){}) 中回调函数不执行 url 中的 json 格式不正确 ,浏览器返回并没有报错 {'湖北':[114.11438,30.849429] ...
- js中回调函数,promise 以及 async/await 的对比用法 对比!!!
在编程项目中,我们常需要用到回调的做法来实现部分功能,那么在js中我们有哪些方法来实现回调的? 方法1:回调函数 首先要定义这个函数,然后才能利用回调函数来调用! login: function (f ...
- Promise 异步函数顺序执行
可以满足需求,且使用方法和Promise.all统一 var a = function() { return new Promise(function(resolve, reject) { setTi ...
- ES6新特性:Javascript中内置的延迟对象Promise
Promise的基本使用: 利用Promise是解决JS异步执行时候回调函数嵌套回调函数的问题, 更简洁地控制函数执行流程: 通过new实例化Promise, 构造函数需要两个参数, 第一个参数为函 ...
- AnjularJS异步编程 Promise和$q
Promise,是一种异步处理模式. js代码的函数嵌套会使得程序执行异步代码时很难调试.因为多重嵌套的函数无法确定何时触发回调. 如: funA(arg1,arg2,function(){ func ...
随机推荐
- 挂起(suspend)与线程阻塞工具类LockSupport
挂起(suspend)与线程阻塞工具类LockSupport 一般来说是不推荐使用suspend去挂起线程的,因为suspend在导致线程暂停的同时,并不会去释放任何锁资源. 如果其他任何线程想要访问 ...
- Hadoop学习(7)-hive的安装和命令行使用和java操作
Hive的用处,就是把hdfs里的文件建立映射转化成数据库的表 但hive里的sql语句都是转化成了mapruduce来对hdfs里的数据进行处理 ,并不是真正的在数据库里进行了操作. 而那些表的定义 ...
- python3学习-pickle模块
pickle提供了一个简单的持久化功能.可以将对象以文件的形式存放在磁盘上. 基本接口: pickle.dump(obj, file, [,protocol]) 注解:将对象obj保存到文件file中 ...
- 转载 | 一种让超大banner图片不拉伸、全屏宽、居中显示的方法
现在很多网站的Banner图片都是全屏宽度的,这样的网站看起来显得很大气.这种Banner一般都是做一张很大的图片,然后在不同分辨率下都是显示图片的中间部分.实现方法如下: <html> ...
- JavaWeb——使用会话维持状态3
这次的例子是使用会话给上一个例子添加登陆功能 1.页面逻辑 首先是登陆页面,这里需要输入账号和密码,输入正确后将进入商品列表页面,输入错误将会提示账号或者密码错误 其次是商品列表和购物车页面,添加了注 ...
- LSTM+CRF维特比解码过程
题目:给定长度为n的序列,标签数为m(标签值表示为1,2,....,m),发射概率矩阵E(n * m),其中E[i][j]表示第i个词预测为标签j的发射概率,转移概率矩阵T(m*m),其中T[i][j ...
- 安装Windows Server 2008
下面介绍一下,Windows Server操作系统安装,以及在企业中的应用,在小型企业中可以使用不同的版本搭建不同类型的服务,小型企业中可以搭建Web服务,FTP服务,以及DNS和DHCP服务等,在大 ...
- C#串口类封装 SuperSerialPort
C#串口类封装 SuperSerialPort 基于SerialPort类做了简单的封装方便调用 代码 /// <summary> /// SuperSerialPort /// < ...
- JavaWeb购物车
一.类关系 最近又把JavaWeb方面的知识(Servlet.jsp等)过了一遍,发现以前还是接触的太窄太浅.加上才转到IntelliJ IDEA 上故而想用这个项目练练,就当熟悉熟悉IntelliJ ...
- Top 10 顶级项目管理工具
成功的项目都要归功于成功的项目管理.这些工具帮你踏上成功之旅! 项目管理是成功完成项目并使公司变得伟大的秘诀.不,这不是标题党(clickbait) -- 我已经看到两家软件公司(我在那里工作)因为项 ...