更新 2019-07-17 

function abc(): Promise<string>{
return new Promise(resolve => {
resolve('dada');
console.log('yeah')
});
}

resolve 之后你再调用 resolve 外部是不会理会的, 这和 .next 不同

另外 resolve 也不等于 return;

resolve 之后的代码依然会执行.

Promise 是 ES 6

Async/Await 是 ES 7

Rxjs 是一个 js 库

在使用 angular 时,你会经常看见这 3 个东西.

它们都和异步编程有关,有些情况下你会觉得用它们其中任何一个效果都一样. 但又觉得好像哪里不太对....

这篇就来说说,我在开发时的应用方式.

在 Typescript 还没有支持 Async/Await 的时候, angular 就已经发布了.

那时我们只想着 Promise vs Rxjs

这 2 者其实很好选择, 因为 "可读性" 和 "代码量" 是差不错的.

而 Rxjs 有一些 Promise 没有的特性.

比如一堆的 operator, 这让我们很方便的操作 stream, 这是 Promise 没有的. (可以去看看如何用 rxjs 来实现 search text, triple click 等等, 几行代码就可以完成了)

此外 Rxjs 可以持续的监听和响应, 这点也是 Promise 做不到的.

所以绝大部分情况下,我们鼓励开发者使用 Rxjs.

而在 angular 自带的多种方法中,默认返回的也都是 Rxjs.

结论是 :

a.如果要持续监听和响应或则要用 operator 那么一定是选 Rxjs

b.其它情况就对比 2 者的 "可读性" 和 "代码量" (在没有 Async/Await 的年代, 它们是一样的), 所以还是选 Rxjs 就对了.

后来, Typescript 支持了 Async/Await

这让情况发生了变化.

Async/Await 的 "可读性" 是比 Promise 要好的 (代码越复杂,可读性就越好)

所以刚刚的结论 a 依然没有改变

但是结论 b 就有了变数.

下面我们来看看对比的代码

我们说 Async/Await 可读性高是指 "它的返回方式和我们写同步代码很相似"

let a = getData(); // 同步代码

let a = await getDataAsync(); // Async/Await 代码 

这是它好读的原因.

但是呢.. 当我们加上错误处理时,它也许就没有那么好了.

async click()
{
try
{
let a = await getDataAsync();
}
catch(e)
{
// handle error
}
}

Async/Await 是用 catch 来捕获的.

这和 java, c# 类似, 读起来还算可以, 但是如果你有多个异步代码, 而且要不同的错误处理呢 ?

async click()
{
try
{
let a = await this.http.get('urlA');
let b = await this.http.get('urlB');
let c = await this.http.get('urlC');
}
catch(e)
{
// 我们需要在这里识别出不同的 error 做不同的处理
}
}

把成功和失败的逻辑分开, 并不会让代码更好读, 而且还需要写识别错误的逻辑...

所以我们可以这样写

async click()
{
try
{
let a = await this.http.get('urlA').catch(e => {
this.errorMessage = 'A failed';
throw '';
});
let b = await this.http.get('urlB').catch(e => {
this.errorMessage = 'B failed';
});
let c = await this.http.get('urlC');
}
catch(e)
{
// 什么都不处理
}
}

勉强还行... 但是为什么 .catch 里面还需要 throw 呢 ? 为什么有一个 "什么都不处理呢" ?

这是因为

let a = await this.http.get('urlA').catch(e => {
this.errorMessage = 'A failed';
// 假设没有 throw, let a 会是 undefined, let b, let c 会继续执行...
// 假设 return whatever, let b, let c 也会执行.
// 你要中断 let b, let c 只有 2 个方法.
// 1. throw '';
// 2. Promise.reject('');
// 这是 Async/Await 和 Promise 不同的地方
});

一旦你 throw 了, 外面就要有人 catch 不然就会 throw 到 angular 的 catch 里头了 (注意我的 click 是 component 的方法).

所以就有了一个

catch(e)
{
// 什么都不处理, 其实是为了防止 throw 到 angular 的 catch 里头 /.\
}

写 Promise 是不需要 try catch 的,因为 Promise 一旦进入 reject 就不可能进入下一个 then 了, 而 Async/Await 需要配搭 try catch throw.

结论 :

a.如果要持续监听和响应或则要用 operator 那么一定是选 Rxjs

b.其余情况就看个人了

-看惯了 Promise, 又看不惯 try catch 的话建议用 Promise 就好了.

-但如果 2 种方式你都看的习惯, 那么建议写 Async/Await 吧

因为看不惯 Promise 的人, 你写 Promise, 他就死了.

可是看不惯 try catch 的人, 你写 try catch, 他还死不了.

另外,

Rxjs 有一个 toPromise 的功能, 这有时候让人很困惑的...

要知道 Rxjs.toPromise() 只有在 rxjs.complete 时才会触发.

也就是说如果一个 rxjs 它需要持续监听, 那么你用 toPromise 就会毁了. 一定要用 subscribe

angular 的 http 发了 ajax 后就会 complete 了, 所以你可以使用 toPromise, 但是 ActivatedRoute.paramMap 你 toPromise 就完蛋了, 它不会 complete 所以也就不会触发你的 promise 事件.

angular2 学习笔记 ( Rxjs, Promise, Async/Await 的区别 )的更多相关文章

  1. angular2 学习笔记 ( rxjs 流 )

    RxJS 博大精深,看了好几篇文章都没有明白. 范围牵扯到了函数响应式开发去了... 我对函数式一知半解, 响应式更是第一次听到... 唉...不过日子还是得过...混着过先呗 我目前所理解的很浅,  ...

  2. C#线程学习笔记九:async & await入门二

    一.异步方法返回类型 只能返回3种类型(void.Task和Task<T>). 1.1.void返回类型:调用方法执行异步方法,但又不需要做进一步的交互. class Program { ...

  3. C#线程学习笔记十:async & await入门三

    一.Task.Yield Task.Yield简单来说就是创建时就已经完成的Task,或者说执行时间为0的Task,或者说是空任务,也就是在创建时就将Task的IsCompeted值设置为0. 我们知 ...

  4. C#线程学习笔记八:async & await入门一

    一.涉及内容 async & await是C# 5.0引入的,控制台输出所使用的$符号(拼接字符串)是C# 6.0引入的,其功能类似于string.Format()方法. 二.多线程.异步.同 ...

  5. angular2 学习笔记 (Typescript)

    1.接口奇葩验证 interface Abc { name : string } function abc(obj : Abc) { } let ttc = { name: "adad&qu ...

  6. Koa2学习(二)async/await

    Koa2学习(二)async/await koa2中用到了大量的async/await语法,要学习koa2框架,首先要好好理解async/await语法. async/await顾名思义是一个异步等待 ...

  7. JavaScript:学习笔记(9)——Promise对象

    JavaScript:学习笔记(9)——Promise对象 引入Promise Primose是异步编程的一种解决方案,比传统的解决方案回调函数和事件更加合理和强大.如下面为基于回调函数的Ajax操作 ...

  8. vue使用技巧:Promise + async + await 解决组件间串行编程问题

    业务场景描述 大家都通过互联网投递过简历,比如在智联.58.猎聘等平台.投递心仪的职位前一般都需要前提创建一份简历,简历编辑界面常规的布局最上面是用户的个人基本信息,如姓名.性别.年龄.名族等,接着是 ...

  9. promise async await使用

    1.Promise (名字含义:promise为承诺,表示其他手段无法改变) Promise 对象代表一个异步操作,其不受外界影响,有三种状态: Pending(进行中.未完成的) Resolved( ...

随机推荐

  1. 【转】UML的9种图例解析

    UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中, ...

  2. JavaScript ES6 的let和const

    1 作用域和提升 1.1 作用域(Scope) 某个变量名或者函数名,在某个程序片段中是否可见或者可访问,如果是,那么这个程序片段就是这个变量名或者函数名的作用域.比如: var name = &qu ...

  3. .NET Core开源API网关 – Ocelot中文文档

    Ocelot是一个用.NET Core实现并且开源的API网关,它功能强大,包括了:路由.请求聚合.服务发现.认证.鉴权.限流熔断.并内置了负载均衡器与Service Fabric.Butterfly ...

  4. 剑指Offer-数组中重复的数字

    package Array; /** * 数组中重复的数字 *在一个长度为n的数组里的所有数字都在0到n-1的范围内. * 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次 ...

  5. 【Python】 virtualenv虚拟环境建设和管理

    [virtualenv] 用Python开发时面临的一个大问题就是每个项目需要的依赖包不一致.如果是包本身不一样倒还好,如果不同项目需要的是不同版本的包的话就会很麻烦.如果采用统一的系统Python环 ...

  6. 【Python】 SQLAlchemy的初步使用

    SQLAlchemy 在很多Python的web框架中都整合进了SQLAlchemy这个主要发挥ORM作用的模块.所谓ORM,就是把复杂的SQL语句给包装成更加面向对象,易于理解的样子.在操作数据库的 ...

  7. 【CSS】 CSS 定位

    css 定位和浮动 *******本章大量内容copy自w3school********* 定位对于html界面还是很重要的,因为定位会直接影响到用户的视图.对于css而言,定位也比较灵活. 浮动是一 ...

  8. 0x02 译文:Windows桌面应用Win32第一个程序

    本节课我们将用C++ 写一个最简单的Windows 程序. 目录: 创建一个窗口 窗口消息 编写窗口过程 绘制窗口 关闭窗口 管理应用程序状态 代码如下: #ifndef UNICODE #defin ...

  9. python学习笔记1——基础

    1)注释 单行注释以#开头,例:#第一个注释 多行注释可用多个#号,还有'''和""",例: #第一行注释 #第二行注释 ''' 第三行注释 第四行注释 ''' &quo ...

  10. python爬虫---抓取优酷的电影

    最近在学习爬虫,用的BeautifulSoup4这个库,设想是把优酷上面的电影的名字及链接爬到,然后存到一个文本文档中.比较简单的需求,第一次写爬虫.贴上代码供参考: # coding:utf-8 i ...