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 ...
随机推荐
- ASP.NET Core MVC 之视图组件(View Component)
1.视图组件介绍 视图组件是 ASP.NET Core MVC 的新特性,类似于局部视图,但它更强大.视图组件不使用模型绑定,并且仅依赖于调用它时所提供的数据. 视图组件特点: 呈块状,而不是整个响应 ...
- 转载 | CSS实现单行、多行文本溢出显示省略号(…)
本文引自:https://www.cnblogs.com/wyaocn/p/5830364.html 首先,要知道css的三条属性. overflow:hidden; //超出的文本隐藏 text-o ...
- Redis集群与spring的整合
上一篇详细的赘述了Redis的curd操作及集群的搭建.下面我们开始将他整合到我们实际的项目中去.我的项目采用的是标准的ssm框架,ssm框架这里不说,直接开始整合. 首先在maven管理中将我们的j ...
- JSP前端数据本地排序
在前端中我们经常需要数据的排序,首先写引入我写好的js $(function($) { $('#sclazzId').val($('#voId').val()); document.getElemen ...
- python练习题-1
1.输出正方形 x=input("请输入:") x=int(x) for i in range(0,x): if (i==0) or (i==x-1): print("* ...
- C# 复制Excel单元格格式
本文将介绍通过C# 复制Excel单元格格式的方法,包括复制单元格中的字体.字号.字体加粗.倾斜.单元格背景色.字体颜色.单元格数字格式.单元格文字方向.文字旋转.下划线.单元格对齐方式.单元格边框等 ...
- tab栏切换制作
tab栏切换制作 先上图 要求1:默认状态,第一个选项卡被选中,展示第一个选项卡的内容 策略:第一个选项卡默认有被选中的样式,第一个选项卡对应的display: block,其他的dispaly设为n ...
- JDK1.6 对 synchronized 的锁优化
1. 背景 在 JDK 1.6 中对锁的实现引入了大量的优化. 目的 减少锁操作的开销. 2. 锁优化 在看下面的内容之间,希望大家对 Mark Word 有个大体的理解.Java 中一个对象在堆中的 ...
- Cacti 管理员密码忘记找回
1.登陆数据库: # mysql -uroot -p MariaDB [(none)]> show databases; +--------------------+ | Database | ...
- Flink的JobManager启动(源码分析)
都知道Flink中的角色分为Jobmanager,TaskManger 在启动脚本里面已经找到了jobmanager的启动类org.apache.flink.runtime.entrypoint.St ...