理解Promise的3种姿势
译者按: 对于Promise,也许你会用了,却并不理解;也许你理解了,却只可意会不可言传。这篇博客将从3个简单的视角理解Promise,应该对你有所帮助。
为了保证可读性,本文采用意译而非直译,并且对源代码进行了大量修改。另外,本文版权归原作者所有,翻译仅用于学习。
示例1中,asyncFunc()函数返回的是一个Promise实例:
|
// 示例1
function asyncFunc()
{
return new Promise(function(resolve, reject)
{
setTimeout(function()
{
resolve('Hello, Fundebug!');
}, 100);
});
}
asyncFunc()
.then(function(x)
{
console.log(x); // 1秒之后打印"Hello, Fundebug!"
});
|
1秒之后,Promise实例的状态变为resolved,就会触发then绑定的回调函数,打印resolve值,即”Hello, Fundebug!”。
那么,什么是Promise呢?
- Promise调用是阻塞的
- Promise中保存了异步操作结果
- Promise是一个事件
Promise调用是阻塞的
示例2可以帮助我们理解阻塞:
|
// 示例2
function asyncFunc()
{
return new Promise(function(resolve, reject)
{
setTimeout(function()
{
resolve('Hello, Fundebug!');
}, 1000);
});
}
async function main()
{
const x = await asyncFunc(); // (A)
console.log(x); // (B) 1秒之后打印"Hello, Fundebug!"
}
main();
|
以上代码是采用Async/Await语法写的,与示例1完全等价。await的中文翻译即为”等待”,这里可以”望文生义”。因此,相比于使用Promise实现,它更加直观地展示了什么是阻塞。
- (A)行: 等待asyncFunc()执行,直到它返回结果,并赋值给变量x
- (B)行: 打印x;
事实上,使用Promise实现时,也需要等待asyncFunc()执行,之后再调用then绑定的回调函数。因此,调用Promise时,代码也是阻塞的。
Promise中保存了异步操作结果
如果某个函数返回Promise实例,则这个Promise最初相当于一个空白的容器,当函数执行结束时,其结果将会放进这个容器。示例3通过数组模拟了这个过程:
|
// 示例3
function asyncFunc()
{
const blank = [];
setTimeout(function()
{
blank.push('Hello, Fundebug!');
}, 1000);
return blank;
}
const blank = asyncFunc();
console.log(blank); // 打印"[]"
setTimeout(function()
{
const x = blank[0]; // (A)
console.log(x); // 2秒之后打印"Hello, Fundebug!"
}, 2000);
|
开始时,blank为空数组,1秒之后,”Hello, Fundebug!”被添加到数组中,为了确保成功,我们需要在2秒之后从blank数组中读取结果。
对于Promise,我们不需要通过数组或者其他变量来传递结果,then所绑定的回调函数可以通过参数获取函数执行的结果。
Promise是一个事件
示例4模拟了事件:
|
// 示例4
function asyncFunc()
{
const eventEmitter = {
success: []
};
setTimeout(function()
{
for (const handler of eventEmitter.success)
{
handler('Hello, Fundebug!');
}
}, 1000);
return eventEmitter;
}
asyncFunc()
.success.push(function(x)
{
console.log(x); // 1秒之后打印"Hello, Fundebug!"
});
|
调用asyncFunc()之后,sucesss数组其实是空的,将回调函数push进数组,相当于绑定了事件的回调函数。1秒之后,setTimeout定时结束,则相当于事件触发了,这时sucess数组中已经注册了回调函数,于是打印”Hello, Fundebug!”。
当Promise成功resolve时,会触发then所绑定的回调函数,这其实就是事件。
参考
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/09/25/3-ways-to-understand-promise/
理解Promise的3种姿势的更多相关文章
- 理解Promise的三种姿势
译者按: 对于Promise,也许你会用了,却并不理解:也许你理解了,却只可意会不可言传.这篇博客将从3个简单的视角理解Promise,应该对你有所帮助. 原文: Three ways of unde ...
- 大白话讲解Promise(二)理解Promise规范
上一篇我们讲解了ES6中Promise的用法,但是知道了用法还远远不够,作为一名专业的前端工程师,还必须通晓原理.所以,为了补全我们关于Promise的知识树,有必要理解Promise/A+规范,理解 ...
- 彻底理解Promise对象——用es5语法实现一个自己的Promise(上篇)
本文同步自我的个人博客: http://mly-zju.github.io/ 众所周知javascript语言的一大特色就是异步,这既是它的优点,同时在某些情况下也带来了一些的问题.最大的问题之一,就 ...
- 又拍云张聪:OpenResty 动态流控的几种姿势
2019 年 1 月 12 日,由又拍云.OpenResty 中国社区主办的 OpenResty × Open Talk 全国巡回沙龙·深圳站圆满结束,又拍云首席架构师张聪在活动上做了< Ope ...
- 补习系列(7)-springboot 实现拦截的五种姿势
目录 简介 姿势一.使用 Filter 接口 1. 注册 FilterRegistrationBean 2. @WebFilter 注解 姿势二.HanlderInterceptor 姿势三.@Exc ...
- 160701、理解 Promise 的工作原理
Javascript 采用回调函数(callback)来处理异步编程.从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doo ...
- 160623、理解 Promise 的工作原理
Javascript 采用回调函数(callback)来处理异步编程.从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doo ...
- 理解Promise简单实现的背后原理
在写javascript时我们往往离不开异步操作,过去我们往往通过回调函数多层嵌套来解决后一个异步操作依赖前一个异步操作,然后为了解决回调地域的痛点,出现了一些解决方案比如事件订阅/发布的.事件监听的 ...
- Python 高级特性介绍 - 迭代的99种姿势 与协程
Python 高级特性介绍 - 迭代的99种姿势 与协程 引言 写这个笔记记录一下一点点收获 测试环境版本: Python 3.7.4 (default, Sep 28 2019, 16:39:19) ...
随机推荐
- 快速制作U盘启动盘和U盘安装盘的方法
制作U盘启动盘的方法: 1. 安装UltraISO; 2. 安装完成后,用管理员权限打开UltraISO; 3. 打开启动盘文件,一般为ISO文件: 4. 插入U盘: 5. 选择 启动 -> 写 ...
- 包建强的培训课程(8):iOS与设计模式
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...
- 一篇入门 -- Scala 反射
本篇文章主要让大家理解什么是Scala的反射, 以及反射的分类, 反射的一些术语概念和一些简单的反射例子. 什么是反射 我们知道, Scala是基于JVM的语言, Scala编译器会将Scala代码编 ...
- [Postman]授权(11)
授权过程将验证您是否有权从服务器访问所需的数据.发送请求时,通常必须包含参数以确保请求具有访问权限并返回所需数据.Postman提供的授权类型使您可以轻松处理Postman本机应用程序中的身份验证协议 ...
- Mybatis Cause: java.lang.ClassNotFoundException: Cannot find class:
MyBatis原因:java.lang.ClassNotFoundException:找不到类. 原因你的xml文件中的返回类型错误,没有找到这个类. 检查类名是否正确,检查路径是否正确. 在复制my ...
- 选择IT事业,意味着终身学习
八月,炎阳如火. 前几天书记找我交流,问我离职的原因,我跟他仔细的分析了一下我的职业发展规划和我对于未来的预期,书记也向我分析了一下他所认为的原因,他说,无外乎是三个原因:第一个是钱的问题:第二个是行 ...
- Tools - 正版Windows7系统的下载与安装
下载 微软原版系统下载地址:https://msdn.itellyou.cn/ 根据系统类型.语言和版本,下载合适的系统ISO文件. 例如: Windows 7 Professional with S ...
- tar (child): bzip2: Cannot exec: No such file or directory报错
[root@hejianlai-jenkins ~]# file android-ndk-r8-linux-x86.tar.bz2 android-ndk-r8-linux-x86.tar.bz2: ...
- 基于Electron+.NET Core的前后端分离的跨平台桌面应用
Web做界面比原生桌面界面开发速度真心要快很多,而且组件也多. 分析: 1..NET Core和Electron都是跨平台的. 2.NET Core做后端很方便,但是没有GUI,Electron做桌面 ...
- 03 使用Tensorflow做计算题
我们使用Tensorflow,计算((a+b)*c)^2/a,然后求平方根.看代码: import tensorflow as tf # 输入储存容器 a = tf.placeholder(tf.fl ...