开篇寄语
在学习Vue.js的过程中,肯定会需要用到Promise,即使不使用Vue.js,也会在其他应用场景中使用它,尤其是涉及到各种大型项目的时候,这时候就要搞明白,它是什么,以及如何去使用它了,本篇文章尽量用简短的语言和事例将它讲的清清楚楚。
内容详情
先来搞清楚Promise这个概念,什么是Promise?根据MDN文档的解释,翻译成中文大意是Promise 对象表示异步操作的最终完成(或失败)及其结果值。
可能看起来不太直观,让咱们转换成具体的事例,即需要向服务器请求获得数据,示例如下:
$.ajax({ success:function(){ ... } })
如果碰到嵌套网络请求,例如第一次网络请求成功后回调函数再次发送网络请求,这种代码就会让人很难受,示例如下:
$.ajax({ success:function(){ $.ajax({ ... }) } })
或者下面这样的写法:
$.ajax({ success: function(data) { ... }, complete: function (data) { $.ajax({ success: function(data){ ... } }) } });
那么问题来了,如果嵌套越来越多该如何是好?所以这个时候Promise就发挥出来了它应有的作用了,Promise的基本例子,请参看下方示例:
let promise = new Promise(function(resolve, reject) { ... });
执行函数有两个参数,resolve 和 reject。这些是 JavaScript 语言提供的回调。当调用该函数,该函数在创建新 Promise时自动运行,获得这两个参数值。
为了使Promise有效,执行程序函数应该调用回调函数中的一个,resolve 或 reject。
新的 Promise() 构造函数返回一个 promise 对象。由于Promise函数需要处理异步操作,返回的promise对象应该能够通知执行何时开始、完成(已解决)或因错误而重新调整(拒绝)。
一个 promise 对象具有以下内部属性:
- state
- pending
- fulfilled
- rejected
- result
- undefined
- value
- error
这些内部属性是代码不可访问的,但它们是可检查的。这意味着我们将能够使用调试器工具检查状态和结果属性值,但我们将无法使用程序直接访问它们。
如下所示:
Promise的状态可以是pending、fulfilled或被rejected。resolved或被rejected的promise被称为已解决。
来一个实际例子:
new Promise((resolve, reject) => { resolve("succeed"); })
以上的例子就是Promise的简单应用,调试结果如下:
如果再放入比如reject或者更多的resolve也只是执行第一个resovle而已,其他都会被忽略。
处理Promise的方法有如下几种:
- .then()
- .catch()
- .finally()
分别来说一下它们的使用方法。
- .then()
- 应在 promise 对象上调用 .then() 方法来处理result(解决)或error(拒绝)。
let promise = new Promise(function(resolve, reject) { }); promise.then( (result) => { console.log(result); }, (error) => { console.log(error); } );
当然,也可以选择调用只有一种结果。
promise.then( (result) => { console.log(result); } );
但是,这只是限定于得到result,如果是error的话,则需要下面的写法:
promise.then( null, (error) => { console.log(error) } );
不过,.catch()方法可以更好的处理出现的错误,后面会说到。
先来看个实际例子,集合宝可梦的公开API,来查看各种宠物小精灵的信息,实例如下:
function getPromise(URL) { let promise = new Promise(function (resolve, reject) { let req = new XMLHttpRequest(); req.open("GET", URL); req.onload = function () { if (req.status == 200) { resolve(req.response); } else { reject("There is an Error!"); } }; req.send(); }); return promise; }
获得50个宝可梦信息:
const ALL_POKEMONS_URL = 'https://pokeapi.co/api/v2/pokemon?limit=50'; let promise = getPromise(ALL_POKEMONS_URL); const consumer = () => { promise.then( (result) => { console.log({result}); // Log the result of 50 Pokemons }, (error) => { // As the URL is a valid one, this will not be called. console.log('We have encountered an Error!'); // Log an error }); } consumer();
如果只需要选择错误,可以参看使用.catch()方法的下方内容:
let promise = getPromise(POKEMONS_BAD_URL); const consumer = () => { promise.catch(error => console.log(error)); } consumer();
说了.then和.catch()后,接下来就轮到.finally()了。
.finally()
.finally() 处理程序执行清理操作,例如停止加载程序、关闭实时连接等。无论承诺是解决还是拒绝,都将调用 finally() 方法。它将结果或错误传递给下一个可以再次调用 .then() 或 .catch() 的处理程序。
let loading = true; loading && console.log('Loading...'); // Gatting Promise promise = getPromise(ALL_POKEMONS_URL); promise.finally(() => { loading = false; console.log(`Promise Settled and loading is ${loading}`); }).then((result) => { console.log({result}); }).catch((error) => { console.log(error) });
除了以上三种方法,还有以下6种方法:
- Promise.all
- Promise.any
- Promise.allSettled
- Promise.race
- Promise.resolve
- Promise.reject
Promise.all
设想有这样一种情况,一个业务需要请求2个地方(A和B)的数据,只有A和B的数据都拿到才能走到下一步。试举例如下:
Promise.all([ new Promise((resolve, reject) => { setTimeout(() => { // 请求A resolve('结果A') }, 1000) }), new Promise((resolve, reject) => { setTimeout(() => { // 请求B resolve('结果B') }, 1000) }) ]).then(results => { console.log(results) })
Promise.any
Promise.any([promises]) - 与 all() 方法类似,.any() 也接受一组 promise 以并行执行它们。此方法不会等待所有承诺都解决。当任何一个承诺得到解决时,它就会完成。
Promise.any([ new Promise((resolve, reject) => { setTimeout(() => { // 请求A resolve('结果A') }, 1000) }), new Promise((resolve, reject) => { setTimeout(() => { // 请求B resolve('结果B') }, 1000) }) ]).then(results => { console.log(results) })
Promise.allSettled()
romise.allSettled([promises]) - 此方法等待所有Promise解决(解决/拒绝)并将其结果作为对象数组返回。结果将包含状态(已完成/已拒绝)和值(如果已完成)。在拒绝状态的情况下,它将返回错误原因。
Promise.allSettled([promise_1, promise_2, promise_3]).then(result => { console.log({result}); }).catch(error => { console.log('There is an Error!'); });
Promise.race()
Promise.race([promises]) – 它等待第一个(最快的)promise 解决,并相应地返回结果/错误。
Promise.race([promise_1, promise_2, promise_3]).then(result => { console.log(JSON.parse(result)); }).catch(error => { console.log('An Error Occured'); });
Promise.resolve/reject
Promise.resolve(value) - 它使用传递给它的值来解析一个Promise。它与以下内容相同:
let promise = new Promise(resolve => resolve(value));
Promise.reject(error) – 它拒绝传递给它的错误的promise。它与以下内容相同:
let promise = new Promise((resolve, reject) => reject(error));
以上就是Promise的基本用法了,想必大家已经对此有所掌握了,那么后续在使用Vue.js制作大型项目时会游刃有余许多。
- 我的微信
- 微信扫一扫加好友
- 我的微信公众号
- 扫描关注公众号