https 错误 color 最好的 没有 状态 等于 end
总想着王者荣耀排位赛再提升个等级就弃掉游戏好好学习,然而打了两个周也没升上去,看来是应该换个方向发挥了。
最近看了《javascript Promise 迷离书》,对 Promise 的理解颇有加深。那么就从总结 Promise 开始吧。
抽象描述: promise 是一个规范,提供了一套精心定义的、用来与代表一个可能会在任意时刻完成或失败的异步过程的结果的对象交互的接口。"Promise 把异步处理对象和处理规则进行规范化, 并按照采用统一的接口来编写,而采取规定方法之外的写法都会出错。"--《javascript Promise 迷离书》第一章。(大概就是知道用 promise 来干什么的时候才能清楚这段话的意思吧)
简单描述:promise 是一个异步对象,在 Promise 对象创建时可能是未知的, 状态变换后 Promise 表示一个异步操作的最终结果,与之进行交互的方式主要是
方法,该方法注册了两个回调函数,它允许你为异步代码执行结果的成功和失败分别绑定相应的处理方法(handlers ),用于处理 resolve 的 value(常用变量名)或 reject 的 reason(常用变量名)。
- then
new Promise 构造器之后,会返回一个 promise 对象,创建 Promise 对象的基本语法:
- new Promise(function(resolve, reject) {
- // 异步处理
- // 处理结束后、判定什么情况下resolve这个Promise,什么情况下reject这个Promise.
- // 通常resolve(value),将promise的状态转变成成功,value为之后要用的值
- // 通常reject(reason),将promise的状态转变为失败,reason为之后错误处理需要用的值
- if (
- /* 异步操作成功的判定条件 */
- ) {
- resolve(value);
- } else {
- reject(reason);
- }
- });
new 一个 Promise 对象,给 Promise 构造函数传递的参数是一个函数(Promise 构造函数只接受函数作为参数,不然是真的会报错给你看的)。该函数带有两个参数 resolve 和 reject。在 Promise 内部实现中会给这个函数参数 resolve 和 reject 传递两个回调函数。代码参考 es6-promise,修改理解大概如下图中的 Promise 的构造函数内的 resolvePromise 和 rejectPromise 函数。resolvePromise 它会对传递进来的 value 值进行处理,rejectPromise 它会对传递的 reason 值进行处理。这段代码做的事情就是,new 一个 Promise 对象,传递给 Promise 对象的函数内部执行了 resolve(value), 就相当于执行了 resolvePromise(value), 同理 reject。
- function Promise(resolver) {
- resolver(function resolvePromise(value) {
- _resolve(
- /*......*/
- , value);
- },
- function rejectPromise(reason) {
- _reject(
- /*......*/
- , reason);
- });
- }
那么 resolve 和 reject 主要做了什么事情了?如下图创建的 testResolvePromise,在 Promise 构造函数接受的函数内部执行了 resolve。testResolvePromise 对象的 [[PromiseStatus]] 值是 "resolved",[[PromiseValue]]值 "resolve: value"(这个字符串就是我们传入 resolve 函数的值)。对比 testRrejectPromise,testRrejectPromise 对象的 [[PromiseStatus]] 值是 "rejected",[[PromiseValue]]值 "reject:reason"(这个字符串就是我们传入 reject 函数的值)。resolve 和 reject 改变了 promise 的状态。同时将处理后的值赋给了 Promise 对象的某个属性(为什么是处理后,见后文。如果你 resolve 的 value 值是一个 Promise 对象,那么就不是简单的赋值了。)。
总结:给 Promise 构造函数传递的参数是一个函数(是一个函数)。
用 new Promise 实例化的 promise 对象有三个状态: pending,fulfilled,rejected。
pending:promise 对象刚被创建的初始状态,既未完成也没有失败的状态,此状态可以迁移至 fulfilled 和 rejected 状态。
fulfilled:意味着操作成功完成, resolve(成功) 时,此时的状态不能迁移 (不能改变的)。
rejected:意味着操作失败 reject(失败) 时,此时的状态不能迁移 (不能改变的)。
eg: 如图创建了一个 testPromisePending 对象,用 setTimeout 设置一个时间 10 秒后再执行 resolve。在这时间段前还没有执行 resolve,此时的 testPromisePending 的 [[PromiseStatus]] 值是 "pending"。10 秒过后再在控制太输出一次 testPromisePending,此时它的状态就迁移了 [[PromiseStatus]] 值是 "resolved",即是 fulfilled 状态。
"promise 对象的状态,从 Pending 转换为 Fulfilled 或 Rejected 之后, 这个 promise 对象的状态就不会再发生任何变化",--《javascript Promise 迷离书》(书中的流程图十分的清晰,有利于 promise 的工作流程理解)
pending 状态 ---->resolve(value)----->fulfilled 状态.
pending 状态 ---->reject(reason)----->rejected 状态.
总结:如果一个 promise 不是 pending 状态,就说明这个 promise 是 settled(不变的),它要么 fulfilled 状态要么是 rejected 状态。
把这个方法单独拿出来说,只是为了承接上文,Promise 构造函数接受一个函数作为参数,函数里面内部代码执行了 resolve 或 reject 后续可以干什么,有 resolve(value) 或 reject(reason) 传递了值后续怎么处理?这时候 then 方法闪亮登场了,promise 的 then 方法里面可以设置 resolve(value) 或 reject(reason) 时调用的回调函数。then 方法接受两个可选参数,当两个参数不是函数就会被忽略掉。
- var testPromise = new Promise(function(resolve, reject) {
- if (
- /* 异步操作成功的判定条件 */
- ) {
- resolve(value);
- //函数内部resolve了value值,那么我们怎么处理value值了;
- } else {
- reject(error);
- //函数内部reject了reason值,那么我们怎么处理reason值了;
- }
- });
- testPromise.then(function onFulfilled(value) {
- //当testPromise的状态是fulfilled的时候执行
- },
- function onRejected(reson) {
- //当testPromise的状态是rejected的时候执行
- })
pending 状态 ---->resolve(value)----->fulfilled 状态 ----> 执行 then 方法里面 onFulfilled(value)方法
pending 状态 ---->reject(reason)----->rejected 状态 ----> 执行 then 方法里面 onRejected(reason) 方法
当 testPromise 的状态迁移成 fulfilled 或 rejected 的时候时才执行后续的 then 方法。testPromise 的状态是 fulfilled 就执行 onFulfilled 方法,此时的 value 参数的值就是之前 resolve 的值,onFulfilled 函数内部就可以对 fulfilled 的 promise 和传递进来 value 值进行后续的处理了。testPromise 的状态是 rejected 就执行 onRejected 方法,此时的 reason 参数的值就是之前 reason 的值,onRejected 函数内部就可以对 rejected 的 promise 和传递进来 reason 值进行后续的处理了。 (上面的路线只会执行一条,)
对了 then 执行完后返回的结果还是一个 promise 对象,妈呀这么执行下去 promise 是不是没完没了呀?对呀对呀这就是后续为什么 promise 适合处理某些场景的原因之一(加粗,加粗,后面需要解释)。每次调用 then 都会返回一个新创建的 promise,神奇了!!还有更更神奇的事儿,这个新创建的 promise 跟 then 方法执行的回调 onFulfilled 和 onRejected 有关系(废话)。
⑴. 调用 then 方法会返回的 promise 是新创建的
⑵. 这个新创建 promise 的值跟 onFulfilled 和 onRejected 的函数内部有无 return 以及 return 的值有关系。如果没有 return 则返回一个状态为 fulfilled 的 [[PromiseValue]](不同实现内部属性不一定叫 PromiseValue)为 undefined 的 promise 对象。
⑶. 承接⑵如果有 return,retuen 一个普通的 object 对象那么新创建 promise 对象的 [[PromiseValue]] 的值就等于 object。 如果 return 的是一个 Promise 对象,还是会返回一个新的 promise 对象,且属性值和 return 的 Promise 对象值一样
返回了一个普通的 promise,imANewPromiseB 长什么样子
- var testPromiseA = new Promise(function(resolve, reject) {
- resolve("testPromiseA")
- });
- var testForreturnPromise = new Promise(function(resolve, reject) {
- resolve("just test for testPromiseB")
- });
- //返回了一个普通的promise,imANewPromiseB长什么样子
- var imANewPromiseB = testPromiseA.then(function onFulfilled(value) {
- //返回了一个promise
- return testForreturnPromise
- })
- // 在控制台输出,imANewPromiseB和 testForreturnPromise 的属性值一样,但他们不是同一个promise。
- //imANewPromiseB 是一个新的promise 对象
在控制台输出,imANewPromiseB 和 testForreturnPromise 的属性值一样,但他们不是同一个 promise,且 imANewPromiseB 和 testPromiseA 也不是同一个 promise 对象。imANewPromiseB 是一个新的 promise。
总结:每次调用 then 都会返回一个新创建的 promise 对象。
有一个作用就是把代码从异步回调函数拯救出来,让代码看起来逻辑清晰可爱。因为 Promise 把异步处理对象和处理规则进行规范化。
- function getJSON(url) {
- return new Promise(function(resolve, reject) {
- let xhr = new XMLHttpRequest(); //神奇的对象
- xhr.open('GET', url);
- xhr.onreadystatechange = handler;
- // 无论readyState值何时发生改变,XMLHttpRequest对象都会激发一个readystatechange事件,handler被调用,然后根据结果resolve,或者reject
- xhr.responseType = 'json';
- xhr.setRequestHeader('Accept', 'application / json');
- xhr.send();
- function handler() {
- if (this.readyState === this.DONE) {
- if (this.status === 200) {
- resolve(this.response);
- //successDo(this.response)
- } else {
- reject(new Error('getJSON: `' + url + '`failed with status: [' + this.status + ']'));
- //faileDo(this.response)
- }
- }
- };
- });
- }
- // 使用promise
- getJSON(url).then(function onFulfilled(value) {
- //successDo
- },
- function onRejected(reson) {
- //faileDo
- })
- // 使用回调
- getJSON(url, successDo, faileDo)
使用回调的方式来做 getJSON,拿数据和对拿到数据成功和失败都在一个函数里面操作处理。
使用 promise 来做 getJSON,getJSON 只需要做好自己拿数据,且通过 resolve 和 reject 返回拿数据成功还是失败的逻辑,并不关心成功或失败的处理。后续的 then 方法会根据 getJSON 返回的 promise 的状态执行 onFulfilled 方法或者 onRejected 方法来处理,数据拿成功或者数据拿失败的逻辑。这个流程比较符合人类(我这种人类)的习惯,一步一步执行操作,拿数据返回成功或失败 -----> 处理拿数据成功或失败。
总结:Promise 可以让异步处理对象更像一个流程操作。使用 Promise 的时候要思考 Promise 的适用场景。并不是说在异步处理的时候 Promise 永远都是最好的选择。
Promise (1) 初步接触
来源: http://www.bubuko.com/infodetail-2086775.html