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 ...
随机推荐
- 5.源码分析---SOFARPC调用服务
我们这一次来接着上一篇文章<4. 源码分析---SOFARPC服务端暴露>讲一下服务暴露之后被客户端调用之后服务端是怎么返回数据的. 示例我们还是和上篇文章一样使用一样的bolt协议来讲: ...
- Java | Map排序,工具类改进
package util; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; ...
- C#连接SQL Anywhere 12 数据库
using System;using System.Data.Common; namespace ConsoleApplication27{ class Program { ...
- React 如何搭建脚手架
React 如何搭建脚手架 npm install -g create-react-app //安装 create-react-app react-demo // react-demo ...
- 【作品】超实用C++分数类
引言 我们说,编程语言的精髓在于封装,而面向对象语言完胜面向过程语言的原因就是具有更好的可封装性,而C++就是这样的一种多范型语言,常用而复杂的工作完全不必在每一份源文件中重敲,就好像我们不需要自己手 ...
- Vue系列:Websocket 使用配置
WebSocket 是什么? WebSocket 是一种网络通信协议.而且是在 HTML5 才开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 为什么需要 WebSocket ? 了解计算 ...
- 【POJ - 2385】Apple Catching(动态规划)
Apple Catching 直接翻译了 Descriptions 有两棵APP树,编号为1,2.每一秒,这两棵APP树中的其中一棵会掉一个APP.每一秒,你可以选择在当前APP树下接APP,或者迅速 ...
- 我的C语言学习1
学习是快乐的,尤其是从之前看到一个程序的一头雾水到大致懂了是怎么回事,这个过程是兴奋开心的,让我不断的前进,不能自拔,今天就要结束,总结一下. 1.1-第一个C语言 #include<stdio ...
- Spring 2017 Assignments3
一.作业要求 原版:http://cs231n.github.io/assignments2017/assignment3/ 翻译:http://www.mooc.ai/course/268/lear ...
- 《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?
Java虚拟机是如何加载Java类的? 这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...