热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

八段代码完全控制Promise

1.Promise的马上实行性varpnewPromise(function(resolve,reject){console.log(createapromise);resolve

1.Promise的马上实行性

var p = new Promise(function(resolve, reject){
console.log("create a promise");
resolve("success");
});
console.log("after new Promise");
p.then(function(value){
console.log(value);
});

掌握台输出:

"create a promise"
"after new Promise"
"success"

Promise对象示意将来某个将要发作的事宜,但在建立(new)Promise时,作为Promise参数传入的函数是会被马上实行的,只是个中实行的代码可所以异步代码。有些同学会以为,当Promise对象挪用then要领时,Promise吸收的函数才会实行,这是毛病的。因此,代码中”create a promise”先于”after new Promise”输出。

2.Promise 三种状况

var p1 = new Promise(function(resolve,reject){
resolve(1);
});
var p2 = new Promise(function(resolve,reject){
setTimeout(function(){
resolve(2);
}, 500);
});
var p3 = new Promise(function(resolve,reject){
setTimeout(function(){
reject(3);
}, 500);
});
console.log(p1);
console.log(p2);
console.log(p3);
setTimeout(function(){
console.log(p2);
}, 1000);
setTimeout(function(){
console.log(p3);
}, 1000);
p1.then(function(value){
console.log(value);
});
p2.then(function(value){
console.log(value);
});
p3.catch(function(err){
console.log(err);
});

掌握台输出:

Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
1
2
3
Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}

Promise的内部实现是一个状况机。Promise有三种状况:pending,resolved,rejected。当Promise刚建立完成时,处于pending状况;当Promise中的函数参数实行了resolve后,Promise由pending状况变成resolved状况;如果在Promise的函数参数中实行的不是resolve要领,而是reject要领,那末Promise会由pending状况变成rejected状况。

p2、p3刚建立完成时,掌握台输出的这两台Promise都处于pending状况,但为何p1是resolved状况呢? 这是由于p1 的函数参数中实行的是一段同步代码,Promise刚建立完成,resolve要领就已被挪用了,因此紧跟着的输出显现p1是resolved状况。我们经由历程两个setTimeout函数,耽误1s后再次输出p2、p3的状况,此时p2、p3已实行完成,状况离别变成resolved和rejected。

3.Promise 状况的不可逆性

var p1 = new Promise(function(resolve, reject){
resolve("success1");
resolve("success2");
});
var p2 = new Promise(function(resolve, reject){
resolve("success");
reject("reject");
});
p1.then(function(value){
console.log(value);
});
p2.then(function(value){
console.log(value);
});

掌握台输出:

"success1"
"success"

Promise状况的一旦变成resolved或rejected时,Promise的状况和值就牢固下来了,不管你后续再怎样挪用resolve或reject要领,都不能转变它的状况和值。因此,p1中resolve("success2")并不能将p1的值更改成success2,p2中reject("reject")也不能将p2的状况由resolved转变成rejected.

4.链式挪用

var p = new Promise(function(resolve, reject){
resolve(1);
});
p.then(function(value){ //第一个then
console.log(value);
return value*2;
}).then(function(value){ //第二个then
console.log(value);
}).then(function(value){ //第三个then
console.log(value);
return Promise.resolve('resolve');
}).then(function(value){ //第四个then
console.log(value);
return Promise.reject('reject');
}).then(function(value){ //第五个then
console.log('resolve: '+ value);
}, function(err){
console.log('reject: ' + err);
})

掌握台输出:

1
2
undefined
"resolve"
"reject: reject"

Promise对象的then要领返回一个新的Promise对象,因此能够经由历程链式挪用then要领。then要领吸收两个函数作为参数,第一个参数是Promise实行胜利时的回调,第二个参数是Promise实行失利时的回调。两个函数只会有一个被挪用,函数的返回值将被用作建立then返回的Promise对象。这两个参数的返回值可所以以下三种状况中的一种:

  • return 一个同步的值 ,或许 undefined(当没有返回一个有效值时,默许返回undefined),then要领将返回一个resolved状况的Promise对象,Promise对象的值就是这个返回值。
  • return 另一个 Promise,then要领将依据这个Promise的状况和值建立一个新的Promise对象返回。
  • throw 一个同步非常,then要领将返回一个rejected状况的Promise, 值是该非常。

依据以上剖析,代码中第一个then会返回一个值为2(1*2),状况为resolved的Promise对象,因而第二个then输出的值是2。第二个then中没有返回值,因此将返回默许的undefined,因而在第三个then中输出undefined。第三个then和第四个then中离别返回一个状况是resolved的Promise和一个状况是rejected的Promise,顺次由第四个then中胜利的回调函数和第五个then中失利的回调函数处置惩罚。

5.Promise then() 回调异步性

var p = new Promise(function(resolve, reject){
resolve("success");
});
p.then(function(value){
console.log(value);
});
console.log("which one is called first ?");

掌握台输出:

"which one is called first ?"
"success"

Promise吸收的函数参数是同步实行的,但then要领中的回调函数实行则是异步的,因此,”success”会在背面输出。

6.Promise 中的非常

var p1 = new Promise( function(resolve,reject){
foo.bar();
resolve( 1 );
});
p1.then(
function(value){
console.log('p1 then value: ' + value);
},
function(err){
console.log('p1 then err: ' + err);
}
).then(
function(value){
console.log('p1 then then value: '+value);
},
function(err){
console.log('p1 then then err: ' + err);
}
);
var p2 = new Promise(function(resolve,reject){
resolve( 2 );
});
p2.then(
function(value){
console.log('p2 then value: ' + value);
foo.bar();
},
function(err){
console.log('p2 then err: ' + err);
}
).then(
function(value){
console.log('p2 then then value: ' + value);
},
function(err){
console.log('p2 then then err: ' + err);
return 1;
}
).then(
function(value){
console.log('p2 then then then value: ' + value);
},
function(err){
console.log('p2 then then then err: ' + err);
}
);

掌握台输出:

p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then then value: undefined
p2 then then err: ReferenceError: foo is not defined
p2 then then then value: 1

Promise中的非常由then参数中第二个回调函数(Promise实行失利的回调)处置惩罚,非常信息将作为Promise的值。非常一旦获得处置惩罚,then返回的后续Promise对象将恢复一般,并会被Promise实行胜利的回调函数处置惩罚。别的,须要注重p1、p2 多级then的回调函数是交替实行的 ,这正是由Promise then回调的异步性决议的。

7.Promise.resolve()

var p1 = Promise.resolve( 1 );
var p2 = Promise.resolve( p1 );
var p3 = new Promise(function(resolve, reject){
resolve(1);
});
var p4 = new Promise(function(resolve, reject){
resolve(p1);
});
console.log(p1 === p2);
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);
p4.then(function(value){
console.log('p4=' + value);
});
p2.then(function(value){
console.log('p2=' + value);
})
p1.then(function(value){
console.log('p1=' + value);
})

掌握台输出:

true
false
false
false
p2=1
p1=1
p4=1

Promise.resolve(...)能够吸收一个值或许是一个Promise对象作为参数。当参数是一般值时,它返回一个resolved状况的Promise对象,对象的值就是这个参数;当参数是一个Promise对象时,它直接返回这个Promise参数。因此,p1 === p2。但经由历程new的体式格局建立的Promise对象都是一个新的对象,因此背面的三个比较效果都是false。别的,为何p4的then最早挪用,但在掌握台上是末了输出效果的呢?由于p4的resolve中吸收的参数是一个Promise对象p1,resolve会对p1”拆箱“,猎取p1的状况和值,但这个历程是异步的,可参考下一节。

8.resolve vs reject

var p1 = new Promise(function(resolve, reject){
resolve(Promise.resolve('resolve'));
});
var p2 = new Promise(function(resolve, reject){
resolve(Promise.reject('reject'));
});
var p3 = new Promise(function(resolve, reject){
reject(Promise.resolve('resolve'));
});
p1.then(
function fulfilled(value){
console.log('fulfilled: ' + value);
},
function rejected(err){
console.log('rejected: ' + err);
}
);
p2.then(
function fulfilled(value){
console.log('fulfilled: ' + value);
},
function rejected(err){
console.log('rejected: ' + err);
}
);
p3.then(
function fulfilled(value){
console.log('fulfilled: ' + value);
},
function rejected(err){
console.log('rejected: ' + err);
}
);

掌握台输出:

p3 rejected: [object Promise]
p1 fulfilled: resolve
p2 rejected: reject

Promise回调函数中的第一个参数resolve,会对Promise实行”拆箱”行动。即当resolve的参数是一个Promise对象时,resolve会”拆箱”猎取这个Promise对象的状况和值,但这个历程是异步的。p1″拆箱”后,猎取到Promise对象的状况是resolved,因此fulfilled回调被实行;p2″拆箱”后,猎取到Promise对象的状况是rejected,因此rejected回调被实行。但Promise回调函数中的第二个参数reject不具备”拆箱“的才能,reject的参数会直接传递给then要领中的rejected回调。因此,纵然p3 reject吸收了一个resolved状况的Promise,then要领中被挪用的依然是rejected,而且参数就是reject吸收到的Promise对象。

迎接关注我的民众号:老干部的大前端,领取21本大前端精选书本!

《八段代码完全控制Promise》


推荐阅读
  • 本文将继续探讨前端开发中常见的算法问题,重点介绍如何将多维数组转换为一维数组以及验证字符串中的括号是否成对出现。通过多种实现方法的解析,帮助开发者更好地理解和掌握这些技巧。 ... [详细]
  • 实用正则表达式有哪些
    小编给大家分享一下实用正则表达式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下 ... [详细]
  • 12月16日JavaScript变量、函数、流程、循环等***线上九期班
    12月16日JavaScript变量、函数、流程、循环等***线上九期班 ... [详细]
  • 深入理解Vue.js:从入门到精通
    本文详细介绍了Vue.js的基础知识、安装方法、核心概念及实战案例,帮助开发者全面掌握这一流行的前端框架。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • This post discusses an issue encountered while using the @name annotation in documentation generation, specifically regarding nested class processing and unexpected output. ... [详细]
  • 本文介绍如何从字符串中移除大写、小写、特殊、数字和非数字字符,并提供了多种编程语言的实现示例。 ... [详细]
  • 本文详细介绍如何使用 HTML5 和 JavaScript 实现一个交互式的画板功能。通过具体代码示例,帮助读者理解 Canvas API 的基本用法及其在绘图应用中的实际应用。 ... [详细]
  • 本文回顾了2017年的转型和2018年的收获,分享了几家知名互联网公司提供的工作机会及面试体验。 ... [详细]
  • 版本控制工具——Git常用操作(下)
    本文由云+社区发表作者:工程师小熊摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码、使用分支、出现代码冲突的解决办法、紧急保存现场和恢复 ... [详细]
  • 程序员如何优雅应对35岁职业转型?这里有深度解析
    本文探讨了程序员在职业生涯中如何通过不断学习和技能提升,优雅地应对35岁左右的职业转型挑战。我们将深入分析当前热门技术趋势,并提供实用的学习路径。 ... [详细]
  • 本文详细解析了 offset、client 和 page 坐标系统的不同之处。offset 是相对于当前元素的边界框的距离,与滚动条无关;client 是相对于可视区域(viewport)的距离,也与滚动条无关;page 则是相对于整个文档的距离,受滚动条位置影响。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • docker镜像重启_docker怎么启动镜像dock ... [详细]
  • 本文详细介绍了Java的安装、配置、运行流程以及有效的学习方法,旨在帮助初学者快速上手Java编程。 ... [详细]
author-avatar
昙檀禅潺_162
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有