主要内容
Promise对象是什么
Promise对象是ES6中添加的一个对象,它的作用是简化异步操作代码,把返回的结果封装起来,要么成功,要么失败。
相比起传统的异步JavaScript请求代码,Promise对象可以有效减少异步代码的嵌套层级,使代码更加简洁优雅。
回调地狱(callback hell)
在以前的代码中,如果有一个多重的异步操作,它的代码看起来像这样:
1 2 3 4 5 6 7 |
doSomething(function(result) { doSomethingElse(result, function(newResult) { doThirdThing(newResult, function(finalResult) { console.log('Got the final result: ' + finalResult); }, failureCallback); }, failureCallback); }, failureCallback); |
上面的代码包括3个层次的嵌套,有时候甚至会有更多的嵌套,这样的代码难以理解而且维护成本高。
Promise对象
Promise对象的两个常用方法:then(callback)和catch(callback)
在使用这两个方法之前,先了解一下Promise对象的两种状态:fulfilled和rejected
- fulfilled:操作成功完成
- rejected:操作失败
当操作成功完成,数据就可以被then方法中的回调函数访问,同理,当操作失败,就可以在catch方法中处理错误信息。
创建Promise对象
Promise对象的创建非常简单,不过在创建对象的同时就应该指定操作数据的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//把Promise对象的创建过程包装在函数中 function createPromise(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = () => resolve(xhr.responseText); xhr.onerror = () => reject(new Error(xhr.statusText)); xhr.send(); }); }; //返回Promise对象 var promise = createPromise('company.txt'); |
上面的函数中,创建了一个异步请求数据的Promise对象。
resolve和reject方法
在创建Promise对象的时候,resolve和reject方法基本上都是同时出现,这两个方法返回的都是一个Promise对象,不同的是,resolve返回的对象包含操作成功的数据,而reject则返回一个包含出错原因的对象。
使用then和catch方法
和resolve和reject一样,then和catch也是返回一个Promise对象,因此,它们支持方法的链式调用。
then方法最多接受两个参数:分别对应成功和失败时的回调函数
1 2 3 4 5 6 7 |
var promise = createPromise('company.txt'); promise.then(function(data){//当promise对象操作成功时调用这个回调函数 console.log(data); }, function(error){ //第二个参数,当失败时调用这个回调方法 console.error(error); }) |
在使用then方法的时候,如果它的参数不是一个回调函数,则Promise的当前状态会被直接返回出去,例如:
1 2 3 |
promise.then().then(function(data){ console.log(data); //可以成功输出数据 }) |
由于第一个then没有传入任何参数,Promise对象的数据没有被处理,即它的当前状态没有被改变,因此,Promise对象中保存的数据可以被下层的then访问到。如果第一个then传入的参数是一个回调,则下层then就无法继续使用这些数据:
1 2 3 4 5 6 |
promise.then(function(data){ //参数是一个回调函数 }).then(function(data){ //由于第一个参数是回调函数,即Promise中的数据已被处理, //因此这个then方法已经无法再访问它的数据 console.log(data); }) |
catch方法的使用同样简单,它只有一个参数,处理Promise对象中reject抛出的数据
1 2 3 |
promise.catch(function(error){ console.error(error); }) |
一般来说,我们很少在then中处理错误信息,而是把错误处理交给catch方法处理,好处是当有多个then进行链式调用的时候,可以只使用一个catch方法就可以捕获任何一个then方法产生的错误。
1 2 3 4 5 6 7 |
promise.then(function(data){ //do something }).then(function(data2){ //do other thing }).catch(function(error){ //catch the error }) |
all方法
all方法用于批量执行任务,任何一个任务出错都会导致全部任务失败
1 2 3 4 5 6 7 8 9 10 11 |
var promise1 = new Promise((resolve, reject)=>{ resolve("123"); }) var promise2 = new Promise((resolve, reject)=>{ resolve("456"); }) Promise.all([promise1, promise2]).then(function(values){ console.log(values); }) |
上面代码输出的结果是:[“123”, “456”],结果类型是array。
当执行all的时候,promise并不会保证哪一个任务会先完成,但保证返回数据在values中的顺序。
转载请注明:Pure nonsense » Javascript Promise对象