Promise库
标准
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
- “promise” is an object or function with a
then
method whose behavior conforms to this specification.- “thenable” is an object or function that defines a
then
method.- “value” is any legal JavaScript value (including
undefined
, a thenable, or a promise).- “exception” is a value that is thrown using the
throw
statement.- “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.
- When pending, a promise:
- may transition to either the fulfilled or rejected state.
- When fulfilled, a promise:
- must not transition to any other state.
- must have a value, which must not change.
- When rejected, a promise:
- must not transition to any other state.
- 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
MethodA 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)
- Both
onFulfilled
andonRejected
are optional arguments:
- If
onFulfilled
is not a function, it must be ignored.- If
onRejected
is not a function, it must be ignored.- If
onFulfilled
is a function:
- it must be called after
promise
is fulfilled, withpromise
’s value as its first argument.- it must not be called before
promise
is fulfilled.- it must not be called more than once.
- If
onRejected
is a function,
- it must be called after
promise
is rejected, withpromise
’s reason as its first argument.- it must not be called before
promise
is rejected.- it must not be called more than once.
onFulfilled
oronRejected
must not be called until the execution context stack contains only platform code. [3.1].onFulfilled
andonRejected
must be called as functions (i.e. with nothis
value). [3.2]then
may be called multiple times on the same promise.
- If/when
promise
is fulfilled, all respectiveonFulfilled
callbacks must execute in the order of their originating calls tothen
.- If/when
promise
is rejected, all respectiveonRejected
callbacks must execute in the order of their originating calls tothen
.
then
must return a promise [3.3].promise2 = promise1.then(onFulfilled, onRejected);
- If either
onFulfilled
oronRejected
returns a valuex
, run the Promise Resolution Procedure[[Resolve]](promise2, x)
.- If either
onFulfilled
oronRejected
throws an exceptione
,promise2
must be rejected withe
as the reason.- If
onFulfilled
is not a function andpromise1
is fulfilled,promise2
must be fulfilled with the same value aspromise1
.- If
onRejected
is not a function andpromise1
is rejected,promise2
must be rejected with the same reason aspromise1
.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)
. Ifx
is a thenable, it attempts to makepromise
adopt the state ofx
, under the assumption thatx
behaves at least somewhat like a promise. Otherwise, it fulfillspromise
with the valuex
.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 reasonablethen
methods.To run
[[Resolve]](promise, x)
, perform the following steps:
- If
promise
andx
refer to the same object, rejectpromise
with aTypeError
as the reason.- If
x
is a promise, adopt its state [3.4]:
- If
x
is pending,promise
must remain pending untilx
is fulfilled or rejected.- If/when
x
is fulfilled, fulfillpromise
with the same value.- If/when
x
is rejected, rejectpromise
with the same reason.- Otherwise, if
x
is an object or function,
- Let
then
bex.then
. [3.5]- If retrieving the property
x.then
results in a thrown exceptione
, rejectpromise
withe
as the reason.- If
then
is a function, call it withx
asthis
, first argumentresolvePromise
, and second argumentrejectPromise
, where:
- If/when
resolvePromise
is called with a valuey
, run[[Resolve]](promise, y)
.- If/when
rejectPromise
is called with a reasonr
, rejectpromise
withr
.- If both
resolvePromise
andrejectPromise
are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.- If calling
then
throws an exceptione
,
- If
resolvePromise
orrejectPromise
have been called, ignore it.- Otherwise, reject
promise
withe
as the reason.- If
then
is not a function, fulfillpromise
withx
.- If
x
is not an object or function, fulfillpromise
withx
.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 rejectpromise
with an informativeTypeError
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
, andfinally
. An error inpromisedStep1
will flow all the way to
thecatch
function, where it’s caught and handled. (HerepromisedStepN
is
a version ofstepN
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
评价Promise
https://www.zhihu.com/question/25413141
如果着眼于现在和未来一段时间的话,建议用Promise,不论是ES6的还是用Q还是用bluebird,毫无疑问立即马上开始用。
如果眼光放长一点看的话,用了co以后基本上再也不愿回去了,即使是“正宫娘娘”Promise。
这co完全就是用yield/generator实现了async/await的效果啊,第一次见的时候,真是有种天马行空的感觉(原谅我见识少)。
它不仅能够“同步非阻塞”,也几乎没有剥夺我对多个非阻塞操作依赖关系或者竞争关系的精确控制,当我需要精确控制异步流程的时候,回去用Promise甚至callback,当我需要写的爽,一泻千里的时候,用async/await(扯远了)。
Promise库的更多相关文章
- 小而美的Promise库——promiz源码浅析
背景 在上一篇博客[[译]前端基础知识储备--Promise/A+规范](https://segmentfault.com/a/11...,我们介绍了Promise/A+规范的具体条目.在本文中,我们 ...
- 一步一步实现基于Task的Promise库(二)all和any方法的设计和实现
在上一篇中我们已经初步完成了Task类,如果仅仅是这些,那么没有多大意义,因为网上这类js库有很多,现在我们来些更复杂的使用场景. 如果我们现在有这样一个需求:我们要先读取aa.txt的内容,然后去后 ...
- 一步一步实现基于Task的Promise库(一)Promise的基本实现
如果我们现在有一个需求,大概是先读取一个文件的内容,再把得到的内容传给后台去解析,最后把解析后的结果再保存到那个文件,按照最原始的做法代码就是下面这个样子的: //读取文件的原始内容 var read ...
- node.js的Promise库-bluebird示例
前两天公司一哥们写了一段node.js代码发给我,后面特意提了一句“写的不太优雅”.我知道,他意思是回调嵌套回调,因为当时比较急也就没有再纠结.然而内心中总记得要解决这个问题.解决node.js的回调 ...
- 一步一步实现基于Task的Promise库(五)waitFor和waitForAny的实现
在实现waitFor方法之前,我们先要搞明白下面这些问题: 1. waitFor方法的形参有限制吗? 没有!如果形参是Task类型,不应该启动Task,如果是function类型,会执行方法.所以wa ...
- node promise库bluebird
var fs = require('fs') var Promise = require("bluebird") function file1() { return new Pro ...
- 自己实现一个Promise库
源码地址 先看基本使用 const promise = new Promise((resolve, reject) => { resolve(value) // or reject(reason ...
- 一步一步实现基于Task的Promise库(四)无参数的WorkItem
接着上一篇我直接给出代码,现在支持了new Task(), then(), all(), any() 这些不传参的调用方式. (function(){ var isFunction = functio ...
- 一步一步实现基于Task的Promise库(三)waitFor方法的设计
在上一篇中我们已经完成了Task.js里面的all和any方法,已经可以完美的解决大部分需求,我们再来看一个需求: 我们要先读取aa.txt的内容,然后去后台解析,同时由用户指定一个文件,也要读取解析 ...
随机推荐
- CG-CTF simple-machine
运行一下,输入flag: 用ida打开: input_length和input_byte_804B0C0为重命名的变量:现在一个个看调用的函数. sub_8048526(): 这个函数使用了mmap分 ...
- Ecto中的changeset,schema,struct,map
概要 schema changeset struct map 总结 概要 Ecto 中, 对数据库的操作中经常用到 4 个类型: schema changeset struct map 在 Ecto ...
- 第一课android开发之在activity间传递参数
一.活动间简单参数传递:1.在布局中添加按钮,用<Button,用id设置id名称,id="@+id/这儿填写你要设置成的名称":用text设置按钮上显示的文字.text=& ...
- pyecharts使用
安装 pyecharts 兼容 Python2 和 Python3.目前版本为 0.1.2 pip install pyecharts 入门 首先开始来绘制你的第一个图表 from pyecharts ...
- 15 Django REST Framework 给api添加自定义搜索条件
一.ListModelMixin源码 # 源码 class ListModelMixin(object): """ List a queryset. "&quo ...
- 增强for
什么是增强for? 增强for(也称之为for each)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的.他的内部原理其实是一个Iterator迭代器,所以在遍历过程中不能对集合 ...
- 菜鸟学IT之python3关于列表,元组,字典,集合浅认识!
作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2753 一.列表,元组,字典,集合分别如何增删改查及遍历. 列表 # 列表的 ...
- 前端可视化项目流程,涉及three.js(webGL),3DMax技术,持续更新
最近在做一个可视化展示的项目,记录一下流程: 建模,模型来源,可以参考沙盘展示类项目,自己建模或者拼装其他源模型(本人以前是3D建模师,可以应付一些简单的场景) 有效模型导入到web端,这里采用的ob ...
- Oracle计算两天两个日期间相差的天数
Oracle计算两天两个日期间相差的天数: select to_date('19930411','yyyymmdd')-to_date('19890507','yyyymmdd') from dual ...
- 一、Subversion服务
Subversion是优秀的版本控制工具简称SVN,搭建SVN服务器,通过TortoiseSVN进行版本管理. 一.管理SVN服务的VisualSVN和TSVN两种Visual Studio扩展工具 ...