标准

https://promisesaplus.com/

An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.

A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.

Terminology

  1. “promise” is an object or function with a then method whose behavior conforms to this specification.
  2. “thenable” is an object or function that defines a then method.
  3. “value” is any legal JavaScript value (including undefined, a thenable, or a promise).
  4. “exception” is a value that is thrown using the throw statement.
  5. “reason” is a value that indicates why a promise was rejected.

Requirements

Promise States

A promise must be in one of three states: pending, fulfilled, or rejected.

  1. When pending, a promise:
    1. may transition to either the fulfilled or rejected state.
  2. When fulfilled, a promise:
    1. must not transition to any other state.
    2. must have a value, which must not change.
  3. When rejected, a promise:
    1. must not transition to any other state.
    2. must have a reason, which must not change.

Here, “must not change” means immutable identity (i.e. ===), but does not imply deep immutability.

The then Method

A promise must provide a then method to access its current or eventual value or reason.

A promise’s then method accepts two arguments:

promise.then(onFulfilled, onRejected)
  1. Both onFulfilled and onRejected are optional arguments:
    1. If onFulfilled is not a function, it must be ignored.
    2. If onRejected is not a function, it must be ignored.
  2. If onFulfilled is a function:
    1. it must be called after promise is fulfilled, with promise’s value as its first argument.
    2. it must not be called before promise is fulfilled.
    3. it must not be called more than once.
  3. If onRejected is a function,
    1. it must be called after promise is rejected, with promise’s reason as its first argument.
    2. it must not be called before promise is rejected.
    3. it must not be called more than once.
  4. onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].
  5. onFulfilled and onRejected must be called as functions (i.e. with no this value). [3.2]
  6. then may be called multiple times on the same promise.
    1. If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.
    2. If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.
  7. then must return a promise [3.3].

     promise2 = promise1.then(onFulfilled, onRejected);
    1. If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).
    2. If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.
    3. If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.
    4. If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.

The Promise Resolution Procedure

The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.

This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.

To run [[Resolve]](promise, x), perform the following steps:

  1. If promise and x refer to the same object, reject promise with a TypeError as the reason.
  2. If x is a promise, adopt its state [3.4]:
    1. If x is pending, promise must remain pending until x is fulfilled or rejected.
    2. If/when x is fulfilled, fulfill promise with the same value.
    3. If/when x is rejected, reject promise with the same reason.
  3. Otherwise, if x is an object or function,
    1. Let then be x.then. [3.5]
    2. If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
    3. If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise, where:
      1. If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
      2. If/when rejectPromise is called with a reason r, reject promise with r.
      3. If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
      4. If calling then throws an exception e,
        1. If resolvePromise or rejectPromise have been called, ignore it.
        2. Otherwise, reject promise with e as the reason.
    4. If then is not a function, fulfill promise with x.
  4. If x is not an object or function, fulfill promise with x.

If a promise is resolved with a thenable that participates in a circular thenable chain, such that the recursive nature of [[Resolve]](promise, thenable) eventually causes [[Resolve]](promise, thenable) to be called again, following the above algorithm will lead to infinite recursion. Implementations are encouraged, but not required, to detect such recursion and reject promise with an informative TypeError as the reason. [3.6]

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise#Promise_%E5%8E%9F%E5%9E%8B

语法

new Promise( function(resolve, reject) {...} /* executor */  );

参数

executor
executor是带有 resolve 和 reject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数, resolve 和 reject 两个函数作为参数传递给executor(executor 函数在Promise构造函数返回新建对象前被调用)。resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。executor 内部通常会执行一些异步操作,一旦完成,可以调用resolve函数来将promise状态改成fulfilled,或者在发生错误时将它的状态改为rejected。
如果在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。

例子

https://www.jianshu.com/p/459a856c476f

解决回调地狱的方法:

const request = url => {
return new Promise((resolve, reject) => {
$.get(url, data => {
resolve(data)
});
})
}; // 请求data1
request(url).then(data1 => {
return request(data1.url);
}).then(data2 => {
return request(data2.url);
}).then(data3 => {
console.log(data3);
}).catch(err => throw new Error(err));

http://www.cnblogs.com/lvdabao/p/es6-promise-1.html

function runAsync(){
var p = new Promise(function(resolve, reject){
//做一些异步操作
setTimeout(function(){
console.log('执行完成');
resolve('随便什么数据');
}, 2000);
});
return p;
} runAsync1()
.then(function(data){
console.log(data);
return runAsync2();
})
.then(function(data){
console.log(data);
return '直接返回数据'; //这里直接返回数据
})
.then(function(data){
console.log(data);
});

Q库

http://documentup.com/kriskowal/q/#

https://github.com/kriskowal/q

If a function cannot return a value or throw an exception without
blocking, it can return a promise instead. A promise is an object
that represents the return value or the thrown exception that the
function may eventually provide. A promise can also be used as a
proxy for a remote object to overcome latency.

On the first pass, promises can mitigate the “Pyramid of
Doom
”: the situation where code marches to the right faster
than it marches forward.

step1(function (value1) {
step2(value1, function(value2) {
step3(value2, function(value3) {
step4(value3, function(value4) {
// Do something with value4
});
});
});
});

With a promise library, you can flatten the pyramid.

Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
// Do something with value4
})
.catch(function (error) {
// Handle any error from all above steps
})
.done();

With this approach, you also get implicit error propagation, just like try,
catch, and finally. An error in promisedStep1 will flow all the way to
the catch function, where it’s caught and handled. (Here promisedStepN is
a version of stepN that returns a promise.)

The callback approach is called an “inversion of control”.
A function that accepts a callback instead of a return value
is saying, “Don’t call me, I’ll call you.”. Promises
un-invert the inversion, cleanly separating the input
arguments from control flow arguments. This simplifies the
use and creation of API’s, particularly variadic,
rest and spread arguments.

BlueBird库

http://bluebirdjs.com/docs/getting-started.html

http://bluebirdjs.com/docs/features.html

http://bluebirdjs.com/docs/api-reference.html

API Reference

评价Promise

https://www.zhihu.com/question/25413141

如果着眼于现在和未来一段时间的话,建议用Promise,不论是ES6的还是用Q还是用bluebird,毫无疑问立即马上开始用。
如果眼光放长一点看的话,用了co以后基本上再也不愿回去了,即使是“正宫娘娘”Promise。
这co完全就是用yield/generator实现了async/await的效果啊,第一次见的时候,真是有种天马行空的感觉(原谅我见识少)。
它不仅能够“同步非阻塞”,也几乎没有剥夺我对多个非阻塞操作依赖关系或者竞争关系的精确控制,当我需要精确控制异步流程的时候,回去用Promise甚至callback,当我需要写的爽,一泻千里的时候,用async/await(扯远了)。

Promise库的更多相关文章

  1. 小而美的Promise库——promiz源码浅析

    背景 在上一篇博客[[译]前端基础知识储备--Promise/A+规范](https://segmentfault.com/a/11...,我们介绍了Promise/A+规范的具体条目.在本文中,我们 ...

  2. 一步一步实现基于Task的Promise库(二)all和any方法的设计和实现

    在上一篇中我们已经初步完成了Task类,如果仅仅是这些,那么没有多大意义,因为网上这类js库有很多,现在我们来些更复杂的使用场景. 如果我们现在有这样一个需求:我们要先读取aa.txt的内容,然后去后 ...

  3. 一步一步实现基于Task的Promise库(一)Promise的基本实现

    如果我们现在有一个需求,大概是先读取一个文件的内容,再把得到的内容传给后台去解析,最后把解析后的结果再保存到那个文件,按照最原始的做法代码就是下面这个样子的: //读取文件的原始内容 var read ...

  4. node.js的Promise库-bluebird示例

    前两天公司一哥们写了一段node.js代码发给我,后面特意提了一句“写的不太优雅”.我知道,他意思是回调嵌套回调,因为当时比较急也就没有再纠结.然而内心中总记得要解决这个问题.解决node.js的回调 ...

  5. 一步一步实现基于Task的Promise库(五)waitFor和waitForAny的实现

    在实现waitFor方法之前,我们先要搞明白下面这些问题: 1. waitFor方法的形参有限制吗? 没有!如果形参是Task类型,不应该启动Task,如果是function类型,会执行方法.所以wa ...

  6. node promise库bluebird

    var fs = require('fs') var Promise = require("bluebird") function file1() { return new Pro ...

  7. 自己实现一个Promise库

    源码地址 先看基本使用 const promise = new Promise((resolve, reject) => { resolve(value) // or reject(reason ...

  8. 一步一步实现基于Task的Promise库(四)无参数的WorkItem

    接着上一篇我直接给出代码,现在支持了new Task(), then(), all(), any() 这些不传参的调用方式. (function(){ var isFunction = functio ...

  9. 一步一步实现基于Task的Promise库(三)waitFor方法的设计

    在上一篇中我们已经完成了Task.js里面的all和any方法,已经可以完美的解决大部分需求,我们再来看一个需求: 我们要先读取aa.txt的内容,然后去后台解析,同时由用户指定一个文件,也要读取解析 ...

随机推荐

  1. nginx预防常见攻击

    目录 nginx防止DDOS攻击 概述 攻击手段 配置 限制请求率 限制连接的数量 关闭慢连接 设置 IP 黑名单 设置IP白名单 小站点解决方案 nginx防止CC攻击 概述 主动抑制方法 应用举例 ...

  2. 报错TypeError: $(...).live is not a function解决方法

    报错的原因是这个方法在jquery1.7以后就被废除了, 1.7以后的版本改用.on()方法 之前的用法: .live(events, function) 新方法: .on(eventType, se ...

  3. yum 安装 python-pip 失败解决方法

    这个包在EPEL源里,要添加EPEL源才可以.然后按博客里说的方法添加,执行以下命令: sudo rpm -ivh epel-release* 第一种方式:由于epel在禁用列表里需要另外加参数yum ...

  4. tensorflow 训练之tensorboard使用

    1.add saclar and histogram tf.summary.scalar('mean', mean) tf.summary.histogram('histogram', var) 2. ...

  5. ASP.NET Core 搭配 Nginx 的真实IP问题

    一.前言 Nginx(Engine X)是一个高性能HTTP和反向代理服务,是由俄罗斯人伊戈尔·赛索耶夫为访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发 ...

  6. AOP 还在配置吗改用打标签模式吧!

    为什么我喜欢打标签来配置AOP 1. 配置多很混乱,代码里面很难分辨出来哪些是AOP容器(比如属性注入) 2. 对于代码生成器生成的代码里面还需要手动加到配置里面 3. 连java spring现在都 ...

  7. 类Objects

    Object类是什么? 在JDK7添加了一个Objects工具类,它提供了一些方法来操作对象,它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍 ...

  8. Socket网络编程(案例)

    Socket:套接字 java.net包 1.流式套接字:基于TCP协议的Socket网络编程 工作方式: 1.客户端A连接到服务器: 2.服务器建立连接并把客户端A添加到列表: 3.客户端B.C.. ...

  9. C语言之将弧度值转换为角度值

    #include<stdio.h> #include<stdlib.h> #define pi 3.141592 void conver_radian(float radian ...

  10. 石家庄地铁系统开发(java web版)(一)

    今天所完成的任务: 在Mysql数据库中创建了sjzsubstop表和sjzsubway表 sjzsubstop表用于录入所有站点名称和与之对应的stopid(作为主码) sjzsubway表用于录入 ...