Promise最佳实践(转)
本文作者:IMWeb dekuchen 原文出处:IMWeb社区 未经同意,禁止转载
有关Promise的几个问题
基础概念
一:什么是Promise
国内比较流行的看法:
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了
Promise
对象。
Promise 真正的规范,一篇长文。
截取几段:
Terminology
- “promise” is an object or function with a
then
method whose behavior conforms to this specification.- “thenable” is an object or function that defines a
then
method.- “value” is any legal JavaScript value (including
undefined
, a thenable, or a promise).- “exception” is a value that is thrown using the
throw
statement.- “reason” is a value that indicates why a promise was rejected.
从问题来看
1. 是否可以使用return
代替 resolve
不可以,无法实现链式调用,且不符合规范。
示例:
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
return 'this is return';
resolve('true');
console.log('this will not be exec');
throw new Error('error');
}else{
reject('false');
}
})
}
执行结果:
~/chen/FE/winSep/codes/javascript/es6promise/src ts-node return.ts
Promise { <pending> }
- 无法改变状态
- 无法链式调用
2. 使用throw还是reject?
答案: 使用reject
而不是throw
示例:不会被catch的throw Error
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
resolve('true');
console.log('this will be exec');
throw new Error('error');
}else{
reject('false');
}
})
}
console.log(testReturn(true));
执行结果
~/chen/FE/winSep/codes/javascript/es6promise/src ts-node return.ts
this will be exec
Promise { 'true' }
解释:
Promise的构造函数,以及被 then
调用执行的函数基本上都可以认为是在 try…catch
代码块中执行的,所以在这些代码中即使使用 throw
,程序本身也不会因为异常而终止。Promise的状态也不会发生改变。
示例:不使用reject而使用throw
如果在Promise中使用 throw
语句的话,会被 try...catch
住,最终promise对象也变为Rejected状态。
var promise = new Promise(function(resolve, reject){
throw new Error("message");
});
promise.catch(function(error){
console.error(error);// => "message"
});
运行
Error: message
代码像这样其实运行时倒也不会有什么问题,但是如果想把 promise
设置为Rejected状态的话,使用 reject
方法则更显得合理。
所以上面的代码可以改写为下面这样。
var promise = new Promise(function(resolve, reject){
reject(new Error("message"));
});
promise.catch(function(error){
console.error(error);// => "message"
})
总结:如果在Promise中使用 throw
语句的话,会被 try...catch
住,最终promise对象也变为Rejected状态。
2. Promise的执行时间
1. resolve后面的代码会不会被执行?
当没有Error
的时候, resolve
会将Promise.then
放在微任务队列中,当所有的宏任务执行结束的时候,执行微任务队列。
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
resolve('exec true');
console.log('this will be exec');
// throw new Error('error');
}else{
reject('false');
}
})
}
testReturn(true).then(str=>{
console.log(str);
})
执行结果
this will be exec
exec true
当有Error
的时候,Error
后面的代码不会被执行,但是Promise
的结果依旧是fulfilled
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
if(a){
resolve('exec true');
console.log('this will be exec');
throw new Error('error');
console.log('this will not be exec')
}else{
reject('false');
}
})
}
testReturn(true).then(str=>{
console.log(str);
// console.log(testReturn)
}).catch(err=>{
console.log('err: ',err);
})
执行结果
this will be exec
exec true
当Promise遇到setTimeout
看例子:
const testReturn = (a:boolean):Promise<any> =>{
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(a){
resolve('exec true');
console.log('this will be second exec');
}else{
reject('false');
}
})
console.log('this will first be execd');
})
}
testReturn(true).then(str=>{
console.log(str);
// console.log(testReturn)
}).catch(err=>{
console.log('err: ',err);
})
结果
this will first be execd
this will be second exec
exec true
解释:
时间 | 宏任务队列 | 微任务队列 |
---|---|---|
1 | console.log('this will first be execd') |
|
2 | setTimeout |
|
3 | resolve('exec true'); //延迟:因为宏任务没有执行完 |
|
4 | console.log('this will be second exec'); |
|
最终执行顺序:
1->2->4(宏任务结束)->3(微任务结束)
async/await 与Promise
一句话总结:await
等的就是一个Promise
。如果等的不是Promise
,那加了await
和不加没区别
- 将常规的回调转变为
Promise
的方法
function util(args,callback){
if(err){
return callback(err);
}else{
return callback();
}
}
//调用
util(args,(err)=>{
if(err){
}else{
}
})
//Promisify
function utilPromise(args){
return new Promise((resolve,reject)=>{
if(err){
reject(err)
}else{
resolve();
}
})
}
//调用
utilPromise.then().catch()
- 将
Promise
转换为async/await
的方法
async init(){
try{
await utilPromise();//resolve状态
}catch(e){
throw new Error(e); //reject状态
}
}
Promise最佳实践(转)的更多相关文章
- 【转】jQuery最佳实践
上周,我整理了<jQuery设计思想>. 那篇文章是一篇入门教程,从设计思想的角度,讲解"怎么使用jQuery".今天的文章则是更进一步,讲解"如何用好jQu ...
- JavaScript best practices JS最佳实践
JavaScript best practices JS最佳实践 0 简介 最佳实践起初比较棘手,但最终会让你发现这是非常明智之举. 1.合理命名方法及变量名,简洁且可读 var someItem = ...
- nodejs 实践:express 最佳实践(三) express 解析
nodejs 实践:express 最佳实践(三) express 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固, ...
- JQuery系列(7) - JQuery最佳实践
上篇文章是一篇入门教程,从设计思想的角度,讲解"怎么使用jQuery".今天的文章则是更进一步,讲解"如何用好jQuery". 我主要参考了Addy Osman ...
- Typescript 最佳实践
文章列表: <一>大话 TypeScript 基本类型 <二>大话 Typescript 枚举 <三>大话 Typescript 接口 <四>大话 Ty ...
- 结合异步模型,再次总结Netty多线程编码最佳实践
更多技术分享可关注我 前言 本文重点总结Netty多线程的一些编码最佳实践和注意事项,并且顺便对Netty的线程调度模型,和异步模型做了一个汇总.原文:结合异步模型,再次总结Netty多线程编码最 ...
- uni-app 中实现 onLaunch 异步回调后执行 onLoad 最佳实践
前言 好久没写博客了,由于公司业务需要,最近接触uiapp比较多,一直想着输出一些相关的文章.正好最近时间富余,有机会来一波输出了. 问题描述 在使用 uni-app 开发项目时,会遇到需要在 onL ...
- 我的 React 最佳实践
There are a thousand Hamlets in a thousand people's eyes. ----- 威廉·莎士比亚 免责声明:以下充满个人观点,辩证学习 React 目前开 ...
- ASP.NET跨平台最佳实践
前言 八年的坚持敌不过领导的固执,最终还是不得不阔别已经成为我第二语言的C#,转战Java阵营.有过短暂的失落和迷茫,但技术转型真的没有想象中那么难.回头审视,其实单从语言本身来看,C#确实比Java ...
随机推荐
- 命令查询职责分离模式(Command Query Responsibility Segregation,CQRS)
浅谈命令查询职责分离(CQRS)模式 CQRS架构简介 对CQRS的一次批判性思考
- HTTP 错误 500.19 配置文件错误 ( 0x8007000d,0x80070032)
HTTP 错误 500.19 - Internal Server Error无法访问请求的页面,因为该页的相关配置数据无效. 详细错误信息模块 IIS Web Core 通知 未知 处理程序 尚未确定 ...
- C# 把string字符导出到txt文档方法
public static string writtxt(string html, string file) { FileStream fileStream = new FileStream(Envi ...
- sql 查找最后一条记录
1.通过row select * from tablewhere rownum<(select count(*)+1 from table)minusselect * from tablewhe ...
- koa2使用阿里云oss的nodejs sdk实现上传图片
nodejs实现上传图片到阿里云,自然是写成接口形式比较方便,前端监听input file的改变,把file对象传入到formData中传入后端,不能直接传入file对象,后端需要接受formData ...
- windows下nvm安装node之后npm命令找不到问题解决办法
主要关键解解决办法:===>>适用于所有东西的安装 安装有关环境配置类的软件及其他,一般情况下切记不要安装到c盘programfiles下,否则会出现各种问题的报错!!!切记! nvm安装 ...
- 75道阿里Java面试题,你能答上几道?
整理了下阿里近几年的java面试题目,大家参考下吧,希望对大家有帮助,可以帮大家查漏补缺. 答对以下这些面试题,可以淘汰掉 80 % 的求职竞争者. 1.hashcode相等两个类一定相等吗?equa ...
- SQL2005数据库置疑处理
2005中遇到置疑.丢失日志时按照网上常见的MSSQL2000修复方法来做, 结果发现行不通,甚至连一步都做不下去.其实,在MSSQL2005在处理置疑问题的思 路与MSSQL2000是一致的,但具体 ...
- 二维码解析:使用 JavaScript 库reqrcode.js解析二维码
上次使用QRCode.js可以来生成二维码,但是我没有找到有文档说明可以对存在的二维码进行扫描解析其中的内容. 幸亏查找到了可行的解决方案,而且很好使哦!就是reqrcode.js 地址:https: ...
- Linux中什么是块设备 及 lsblk命令的使用
Linux中I/O设备分为两类:字符设备和块设备.两种设备本身没有严格限制,但是,基于不同的功能进行了分类.(1)字符设备:提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取.相反,此类设备支 ...