标准

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. CG-CTF simple-machine

    运行一下,输入flag: 用ida打开: input_length和input_byte_804B0C0为重命名的变量:现在一个个看调用的函数. sub_8048526(): 这个函数使用了mmap分 ...

  2. Ecto中的changeset,schema,struct,map

    概要 schema changeset struct map 总结 概要 Ecto 中, 对数据库的操作中经常用到 4 个类型: schema changeset struct map 在 Ecto ...

  3. 第一课android开发之在activity间传递参数

    一.活动间简单参数传递:1.在布局中添加按钮,用<Button,用id设置id名称,id="@+id/这儿填写你要设置成的名称":用text设置按钮上显示的文字.text=& ...

  4. pyecharts使用

    安装 pyecharts 兼容 Python2 和 Python3.目前版本为 0.1.2 pip install pyecharts 入门 首先开始来绘制你的第一个图表 from pyecharts ...

  5. 15 Django REST Framework 给api添加自定义搜索条件

    一.ListModelMixin源码 # 源码 class ListModelMixin(object): """ List a queryset. "&quo ...

  6. 增强for

    什么是增强for? 增强for(也称之为for each)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的.他的内部原理其实是一个Iterator迭代器,所以在遍历过程中不能对集合 ...

  7. 菜鸟学IT之python3关于列表,元组,字典,集合浅认识!

    作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2753 一.列表,元组,字典,集合分别如何增删改查及遍历. 列表 # 列表的 ...

  8. 前端可视化项目流程,涉及three.js(webGL),3DMax技术,持续更新

    最近在做一个可视化展示的项目,记录一下流程: 建模,模型来源,可以参考沙盘展示类项目,自己建模或者拼装其他源模型(本人以前是3D建模师,可以应付一些简单的场景) 有效模型导入到web端,这里采用的ob ...

  9. Oracle计算两天两个日期间相差的天数

    Oracle计算两天两个日期间相差的天数: select to_date('19930411','yyyymmdd')-to_date('19890507','yyyymmdd') from dual ...

  10. 一、Subversion服务

    Subversion是优秀的版本控制工具简称SVN,搭建SVN服务器,通过TortoiseSVN进行版本管理. 一.管理SVN服务的VisualSVN和TSVN两种Visual Studio扩展工具 ...