Promise 基础 与 使用套路
2018-03-03 19:37
155 查看
Promise 是 ES6 中内置支持的对象
其构造函数接受一个参数, 该参数是一个函数, 该函数有两个参数, 两个参数都是函数, 一个在成功时调用(resolve), 一个在出错时调用(reject)
reject 的参数是 错误信息, 如网络异常, 或用户逻辑错误信息
resolve 的参数一般是 处理(如网络访问)后的数据, 也可以是 另一个 Promise
then 方法
Promise 的对象(如 myPromise) 可以调用 then 方法, then 方法 接受两个参数, 一个是 成功时的回调, 一个是出错时的回调
注意: 千万不要误解 是 Promise的参数 函数 中直接调用的 resolved 和 rejected, Promise的参数 函数 中的 resolve 方法 和 reject 方法 是 Javascript引擎实现的, 它们的作用是 修改 当前 Promise 的 状态 从 等待 到 成功完成 或是 从 等待 到 出错完成.
而 then 方法 做的是 设置一个 callback, 该 callback 会在 Promise 状态改变时 调用 then方法中给定的 resolved 或 rejected 参数函数
简单的例子
复杂点的网络异步的例子
上面then方法给定的 resolved 函数 只是简单的 打印了获得的数据
Javascript 引擎提供的 resolve 方法 可以接受 两种类型的参数
第一种参数是除了Promise对象之外的普通对象, 这时 resolve 方法 会修改 当前 Promise的状态 为 成功完成, 并将 这个 普通对象 作为 处理的结果保存, 将来 传递给 then 方法 的 参数 函数 resolved 作为参数
第二种参数是Promise 对象, 当 resolve 方法发现 参数是 一个 Promise 时, 并不会更改 当前 Promise的 状态, 而是 会 跟踪 参数Promise 的状态, 即 不会立刻就 导致 then 的 resolved 参数函数的触发, 而是会 等 参数Promise 的 状态变化时 才触发, 并且 then 的 resolved 函数的参数 由这个 新的 Promise 中的 resolve 方法 给定
这种 resolve Promise 的特性开发人员似乎不会直接用到
另外 then 参数方法 resolved 是可以有返回值的, 因为 then 方法的返回值是 一个 新的 Promise, 因此可以 链式调用
promise.then(function(data){})
.then(function(data){})
.then(function(data){})
.then(function(data){})
因此可以实现 阶段性的 异步调用, 如 先访问一个 url, 根据获得的数据 访问 另一个 url
这时就可以利用 resolved 的方法的返回值
当返回值是一个 非 Promise 对象 的普通值, 则 then 返回的 Promise 直接就是 成功完成 的状态, 它的 then 方法 中的 resolve 方法 会被调用, 参数 就是 这个 普通值
当返回值是一个 Promise 对象, 则 then 方法 返回 的 Promise 对象 会 跟踪 该 Promise 对象的状态, 直到 这个 Promise 对象 的 状态 改变, 进而触发 then 的 resolve 方法 的调用
总结一下, then 方法 返回的 Promise 的 构造函数的参数函数 其实 是 resolve 了 then 方法 的 resolved 参数函数 的返回值, 这就是利用 之前那个特性实现的
其构造函数接受一个参数, 该参数是一个函数, 该函数有两个参数, 两个参数都是函数, 一个在成功时调用(resolve), 一个在出错时调用(reject)
let myPromise = new Promise( function(resolve, reject){ if (成功){ resolve(数据 或 另一个 Promise); }else{ reject(出错信息) } } );
reject 的参数是 错误信息, 如网络异常, 或用户逻辑错误信息
resolve 的参数一般是 处理(如网络访问)后的数据, 也可以是 另一个 Promise
then 方法
Promise 的对象(如 myPromise) 可以调用 then 方法, then 方法 接受两个参数, 一个是 成功时的回调, 一个是出错时的回调
function resolved(数据){ }; function rejected(错误信息){ }; myPromise.then(resolved, rejected)
注意: 千万不要误解 是 Promise的参数 函数 中直接调用的 resolved 和 rejected, Promise的参数 函数 中的 resolve 方法 和 reject 方法 是 Javascript引擎实现的, 它们的作用是 修改 当前 Promise 的 状态 从 等待 到 成功完成 或是 从 等待 到 出错完成.
而 then 方法 做的是 设置一个 callback, 该 callback 会在 Promise 状态改变时 调用 then方法中给定的 resolved 或 rejected 参数函数
简单的例子
let promise = new Promise(function(resolve, reject){ resolve("hello world"); }); promise.then(function(data){ console.log(data); }) 输出: hello world
复杂点的网络异步的例子
function fetchData(url){ const promise = new Promise(function(resolve, reject){ // 构造 一个 ajax 请求 const client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = function(){ if (this.readyState != 4) { return; } if (this.status == 200){ // 当网络请求成功时调用 resolve 方法, 并传入获取的数据 resolve(this.response); }else{ reject(new Error(this.statusText)); } };; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); }); return promise; } fetchData("data1.json").then( function(data){ console.log(data); } )
上面then方法给定的 resolved 函数 只是简单的 打印了获得的数据
Javascript 引擎提供的 resolve 方法 可以接受 两种类型的参数
第一种参数是除了Promise对象之外的普通对象, 这时 resolve 方法 会修改 当前 Promise的状态 为 成功完成, 并将 这个 普通对象 作为 处理的结果保存, 将来 传递给 then 方法 的 参数 函数 resolved 作为参数
第二种参数是Promise 对象, 当 resolve 方法发现 参数是 一个 Promise 时, 并不会更改 当前 Promise的 状态, 而是 会 跟踪 参数Promise 的状态, 即 不会立刻就 导致 then 的 resolved 参数函数的触发, 而是会 等 参数Promise 的 状态变化时 才触发, 并且 then 的 resolved 函数的参数 由这个 新的 Promise 中的 resolve 方法 给定
let p1 = new Promise( function(resolve, reject){ resolve("hello"); } ) let p2 = new Promise( function(resolve, reject){ // 注: 并不会 改变 当前 Promise 的状态, 需要等待 p1 的执行结论 resolve(p1); } ); p2.then(function(data){ console.log(data); }) 输出: hello
这种 resolve Promise 的特性开发人员似乎不会直接用到
另外 then 参数方法 resolved 是可以有返回值的, 因为 then 方法的返回值是 一个 新的 Promise, 因此可以 链式调用
promise.then(function(data){})
.then(function(data){})
.then(function(data){})
.then(function(data){})
因此可以实现 阶段性的 异步调用, 如 先访问一个 url, 根据获得的数据 访问 另一个 url
这时就可以利用 resolved 的方法的返回值
let p = new Promise( function(resolve, reject){ resolve(1); } ); p.then(function(data){ console.log(data); return 2 }).then(function(data){ console.log(data); return 3 }).then(function(data){ console.log(data); }).then(function(data){ console.log(data); }) 输出: 1 2 3 undefined
当返回值是一个 非 Promise 对象 的普通值, 则 then 返回的 Promise 直接就是 成功完成 的状态, 它的 then 方法 中的 resolve 方法 会被调用, 参数 就是 这个 普通值
当返回值是一个 Promise 对象, 则 then 方法 返回 的 Promise 对象 会 跟踪 该 Promise 对象的状态, 直到 这个 Promise 对象 的 状态 改变, 进而触发 then 的 resolve 方法 的调用
总结一下, then 方法 返回的 Promise 的 构造函数的参数函数 其实 是 resolve 了 then 方法 的 resolved 参数函数 的返回值, 这就是利用 之前那个特性实现的
function fetchData(url){ const promise = new Promise(function(resolve, reject){ const handle = function(){ if (this.readyState != 4) { return; } if (this.status == 200){ resolve(this.response); }else{ reject(new Error(this.statusText)); } }; const client = new XMLHttpRequest(); client.open("GET", url); client.onreadystatechange = handle; client.responseType = "json"; client.setRequestHeader("Accept", "application/json"); client.send(); }); return promise; } fetchData("data1.json").then( function(data){ // 第一把结果获得 console.log(data); // 业务没有完成, 继续发起请求 return fetchData(data.nextURL) } ).then( function(data){ // 第二把结果返回 console.log(data); } )
相关文章推荐
- 前端基础进阶(十三):透彻掌握Promise的使用,读这篇就够了
- Eclipse基础--使用links方式安装Eclipse插件
- Rational Robot 基础使用手册(一)——概述
- Rational Robot 基础使用手册(四)
- Rational Robot 基础使用手册(七)
- Rational Robot 基础使用手册(九)
- Rational Robot 基础使用手册(十二)
- Delphi基础:回调函数及其使用
- Eclipse基础--使用links方式安装Eclipse插件
- Eclipse基础--使用links方式安装Eclipse插件
- Unix基础之 TCP/IP管理及使用
- [软件架构训练基础教程-10]使用标准
- NHibernate0.7 发布,软件基础开发平台以及在软件基础开发平台中使用O/R Mapping
- 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(一)----基础类库部分
- Cookie使用基础
- Eclipse基础--使用links方式安装Eclipse插件
- 企业信息化系统基础——AD:使用C#批量创建帐号
- Rational Robot 基础使用手册(十三)
- Eclipse基础--使用links方式安装Eclipse插件
- Rational Robot 基础使用手册(五)