Chapter 3: Promises

But what if we could uninvert that inversion of control? What if instead of handing the continuation of our program to another party, we could expect it to return us a capability to know when its task finishes, and then our code could decide what to do next?

most new async APIs being added to JS/DOM platform are being built on Promises.

⚠️:

本章immediately这个词非常常见,意思从Job queue behavior的角度是立即地,并非严格地同步的now sense

What Is a Promise?

面对新技术或模式,如果只看代码来了解和学习,一些抽象概念就会失去。

作者在展示代码前,想要完全的解释什么是Promise概念上地。希望这些可以指导你更好地探索集成的Promise理论进入你的异步流动。

出于这个想法,让我们看2个不同的类比。什么是promise。

  1. 未来值
  2. 现在稍后值

Future Value

想象这个场景:在一个快餐馆下一个订单,并支付1.47。我制造了一个request并等待一个value返回(食品)。我开始了一个transaction.

但我需要等待食物烹饪。(异步)

我拿着收款小条,上面有一个订单号码。这个订单号码是一个“I owe you”promise,确保我肯定会得到食品。

小条和订单号码代表:我会在未来某个时刻得到一个value(食品)。 这是一个承诺Promise.

当等待上餐的时候,我做其他的事情。我把订单号当成食品的占位符。这个占位符让这个value time是独立地。它是一个未来的值。 Future Value

当我听到“Order 113!”, 我走向柜台,用小条交换食品。

即:(一旦我的未来值准备好了,我用我的value-promise来换这个value)

但是有其他的结果。 我听到我的订单号,但是当我要交换小条时,服务员告诉我是“抱歉,食品已经卖光了!”(这表面结果可能是成功也可能是失败)

⚠️在代码中,不会如例子这样简单,有可能这个订单号码永远不会被喊道,导致我们进入一个无限期的未解决状态。

Values Now and Later

在开始介绍Promise如何工作时,先说下callbacks! -- how to handle these future values.

(不是很懂)

var x, y = 2;

console.log( x + y ); // NaN  <-- because `x` isn't set yet

因为x未分配值,所以运算失败。

使用回调函数处理,“把x,y相加,如果它们中有一个未赋值,就等待,直到它们都有值了, 把它们相加”

to consistently handle both now and later, we make both of them later: all operations become async.

It's just a first tiny step toward realizing the benefits of reasoning about future values without worrying about the time aspect of when it's available or not.

Promise Value

这里如何通过Promise来表示x+y。

function add(xPromise,yPromise) {
// `Promise.all([ .. ])` 接受一个数组的promises,,等待它们都完成后,返回一个新promise。
return Promise.all( [xPromise, yPromise] ) //当promise被解决,就可以把收到的value(x, y)相加
.then( function(values){
// `values` is an array of the messages
// 从刚才的已解决的promises.
return values[0] + values[1];
} );
} // `fetchX()` and `fetchY()` return promises for
// their respective values, which may be ready
// *now* or *later*.
add( fetchX(), fetchY() ) // we get a promise back for the sum of those
// two numbers.
// now we chain-call `then(..)` to wait for the
// resolution of that returned promise.
.then( function(sum){
console.log( sum ); // that was easier!
} );

像上文的食品订单,一个Promise可以是被拒绝的(也是一个结果,promise类似保证给你一个结果,未必令你满意)。一个拒绝value被叫做rejection reason! 既可能是程序逻辑直接设置的,也可能是从一个运行时间例外暗示地设置。

.then()就是处理Promise的结果的, 既有fulfillment handler, 也有rejection handler.

因为Promises封装了时间依赖状态the time-dependent state ---等待满足或拒绝这个潜在的value--从外部,因此Promises可以被composed(combined, 比如x和y做加法运算)

一旦一个Promise被解决,它就是一个不变的值,如果需要可以多次被observed。

Promises是一个方便的可重复的机制用于封装和组织furture value。

Promises are an easily repeatable mechanism for encapsulating and composing future values.

Completion Event

一个独立的Promise 表现如一个future values。

但是还可以从其他方面思考一个Promise的解决: 作为一个 控制流动机制--一个时间上的this-then-that--2个或多个步骤在一个异步task内。

假设调用一个函数foo(..)来执行一些tasks。我们无需知道它的内部细节。它可能立即完成tasks,也可能过一会。 我们仅仅需要知道当foo(..)完成后我们就可以进行下一个task了。也就是说我们需要一个foo()完成的通知,以便进行后面的工作。

在典型的JS方式内,如果你需要监听一个通知,you'd likely think of that in terms of events.(从事件的角度思考它).   所以我们要监听一个完成事件,它由foo()发出。

var evt = foo( 42 );

// let `bar(..)` listen to `foo(..)`'s completion
bar( evt ); // also, let `baz(..)` listen to `foo(..)`'s completion
baz( evt );

Promise "Events"

foo()创建了并返回了一个Promise实例,这个实例将会被传入bar和baz。

注意,是使用then()来注册一个then event。

(后面的暂停看!!!)


Thenable Duck Typing


Promise Trust

针对传统回调函数的trust问题的各类情况,Promise是如何解决的:

Calling Too Early

Calling Too Late

Promise Scheduling Quirks

Never Calling the Callback

Calling Too Few or Too Many Times

Failing to Pass Along Any Parameters/Environment

Swallowing Any Errors/Exceptions

Trustable Promise?

Trust Built


Chain Flow

  • Every time you call then(..) on a Promise, it creates and returns a new Promise, which we can chain with.
  • Whatever value you return from the then(..) call's fulfillment callback (the first parameter) is automatically set as the fulfillment of the chained Promise (from the first point).

Terminology: Resolve, Fulfill, and Reject

(原理一大堆解释,也没看。)


Error Handling

Pit of Despair

Uncaught Handling

Pit of Success


Promise Patterns

Promise.race([ .. ])

Timeout Race

"Finally"

Variations on all([ .. ]) and race([ .. ])

Concurrent Iterations


Promise API Recap

new Promise(..) Constructor

Promise.resolve(..) and Promise.reject(..)

then(..) and catch(..)

Promise.all([ .. ]) and Promise.race([ .. ])


Promise Limitations

Sequence Error Handling

Single Value

Unwrap/Spread Arguments

Single Resolution

Inertia

Promise Uncancelable

Promise Performance


Review

You Don't Know JS: Async & Performance(第3章, Promises)(未看)的更多相关文章

  1. You Don't Know JS: Async & Performance(第2章,Callbacks)

    Chapter 2: Callbacks. Callbacks are by far the most common way that asynchrony in JS programs is exp ...

  2. You Don't Know JS: Async & Performance(第一章, 异步:now & later)

    Chapter 1: Asynchrony: Now & Later 在一门语言中,比如JavaScript, 最重要但仍然常常被误解的编程部分是如何在一个完整的时间周期表示和操作程序行为. ...

  3. JavaScript 数据访问(通译自High Performance Javascript 第二章) [转]

    JavaScript 数据访问(通译自High Performance Javascript 第二章)   JavaScript 数据访问(翻译自High Performance Javascript ...

  4. Practical Node.js (2018版) 第9章: 使用WebSocket建立实时程序,原生的WebSocket使用介绍,Socket.IO的基本使用介绍。

    Real-Time Apps with WebSocket, Socket.IO, and DerbyJS 实时程序的使用变得越来越广泛,如传统的交易,游戏,社交,开发工具DevOps tools, ...

  5. Node.js——Async

    一:流程控制 为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程 ...

  6. Async Performance: Understanding the Costs of Async and Await

    Stephen Toub Download the Code Sample Asynchronous programming has long been the realm of only the m ...

  7. Js高设笔记1-2章 defer and async

    1,js是由ECMAscript ,dom ,bom组成的专为网页交互而设计的脚本语言.js是脚本语言之一. 2,MIME,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的 ...

  8. [node.js] async/await如何优雅处理异常?

    node.js的世界,从callback开始,不会止于async. 所有人都在骂为什么不能完全进化,其实我感觉这就是老外的细心,为了承上.这也就是为什么async其实就是promise一样,假如不是一 ...

  9. js async await 终极异步解决方案

    既然有了promise 为什么还要有async await ? 当然是promise 也不是完美的异步解决方案,而 async await 的写法看起来更加简单且容易理解. 回顾 Promise Pr ...

随机推荐

  1. fastjson常用方法

    fastjson是一款alibaba公司开发的json工具包.json经常被使用在数据传输方面,因此特意对它的一些常用方法做备注,欢迎看客在评论区补充或指出问题. 首先定义一个实体类,用于我们进行对象 ...

  2. topcoder srm 680 div1

    problem1 link 将限制按照$x$排序.那么$[upTo_{i}+1,upTo_{i+1}]$中数字个数为$quantity_{i+1}-quantity_{i}$.然后进行动态规划.$f[ ...

  3. ODAC(V9.5.15) 学习笔记(三)TOraSession(4)

    4. 数据库信息 名称 类型 说明 GetDatabaseNames 获取对应的数据库对象名称列表 GetSequenceNames GetStoredProcNames GetTableNames ...

  4. ZOJ 3609 Modular Inverse(扩展欧几里得)题解

    题意:求乘法逆元最小正正数解 思路:a*x≡1(mod m),则称x 是 a 关于 m 的乘法逆元,可以通过解a*x + m*y = 1解得x.那么通过EXGcd得到特解x1,最小正解x1 = x1 ...

  5. Mysql的timestamp字段默认值设置问题

    参考: https://www.cnblogs.com/mxwz/p/7520309.html https://www.jb51.net/article/50878.htm https://blog. ...

  6. Spring Boot源码分析

    1.核心: SpringApplication.run(SpringbootdemoApplication.class, args); 内部 2.初始化: new SpringApplication( ...

  7. R语言之正则表达式

    常见与正则表达式相关的函数: grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, fixed = FALSE, use ...

  8. html 之 table cellpadding,cellspacing

    单元格(cell) -- 表格的内容 单元格边距(表格填充)(cellpadding) -- 代表单元格外面的一个距离,用于隔开单元格与单元格空间 单元格间距(表格间距)(cellspacing) - ...

  9. 数据库03_SQL语句

    由于在笔试中遇到写sql语句的题目,犯了低级错误,这里学习并总结一下,遇到相关的继续更新... 数据定义 1.创建数据库 create database testdb; 2.创建空表 需要指明表明.字 ...

  10. 【C#】C# in deep 笔记

    1. delegate and events http://csharpindepth.com/Articles/Chapter2/Events.aspx 2. 显式类型 和 隐式类型 3. 静态类型 ...