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 ...
随机推荐
- 01-Spring Security框架学习
目录 01-Spring Security框架学习 简介 Spring Security 是什么 Spring Security 解决那些问题 Spring Security 的优点 历史背景 Spr ...
- 第十章 Centos7-系统进程管理 随堂笔记
第十章 Centos7-系统进程管理 本节所讲内容: 10.1 进程概述和ps查看进程工具 10.2 uptime查看系统负载-top动态管理进程 10.3 前后台进程切换- nice进程优先级-实战 ...
- todaytt
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.Drawe ...
- 从MYSQL的ibtmp1文件太大说起
1. 啥情况呀 测试环境机器磁盘空间不足的告警打破了下午的沉寂,一群人开始忙活着删数据.但是,不久前刚清理了一波数据,测试环境在没做压测的情况下不至于短短一个月不到就涨了200G数据,于是,我悄悄的 ...
- 直击根源:微信小程序中web-view再次刷新后页面需要退两次
背景 在上一章(直击根源:vue项目微信小程序页面跳转web-view不刷新)解决了vue在小程序回退不刷新的问题之后,会引出了一个刷新的页面需要点击返回两次才能返回上一个页面 问题描述 在A页面从B ...
- 自己实现spring核心功能 一
聊聊spring spring对于java开发者来说,是最熟悉不过的框架了,我们日常开发中每天都在使用它.它有着各种各样的好处,简单易用,得心应手... ... 我们一说到spring就会讲到ioc ...
- Mybatis中使用PageHelper插件进行分页
分页的场景比较常见,下面主要介绍一下使用PageHelper插件进行分页操作: 一.概述: PageHelper支持对mybatis进行分页操作,项目在github地址: https://github ...
- Redis之对象篇——Redis对象系统简介
Redis之对象篇--Redis对象系统简介 前言 之前几篇文章,简单介绍 Redis用到的所有主要数据结构,简单动态字符串(SDS).双端链表.字典.压缩列表.整数集合.跳跃表. 图解Red ...
- Tomcat源码分析 (九)----- HTTP请求处理过程(二)
我们接着上一篇文章的容器处理来讲,当postParseRequest方法返回true时,则由容器继续处理,在service方法中有connector.getService().getContainer ...
- Flink集群Standalone启动脚本(源码分析)
整个Flink集群的角色分为Jobmanager和TaskManager 以Standalone为例来看一下脚本里面是怎样启动集群的 找到源码的dist这里面包含了启动的脚本文件 standalone ...