ES6 Promise 用法讲解
让我们先定义一个test函数这两个resolve,reject可以是任何名称,用来构造函数调用回调函数时候使用
function test (resolve, reject) {
//做一些异步操作如取网络数据
wx.request({
url: "https://www.easy-mock.com/mock/5a223b51707056548f086d8b/hema/sortItems",
success: function (res) {
console.log ('执行成功');
resolve(res.data)
},
fail: function () {
console.log ('执行失败');
reject(false)
}
})}
这个test()函数有两个参数,这两个参数都是函数函数体是then方法的两个参数,如果执行成功,我们将调用resolve(‘res.data’),如果执行失败,我们将调用reject(‘false’)。可以看出,test()函数只关心自身的逻辑,并不关心具体的resolve和reject将如何处理结果。
有了执行函数,我们就可以用一个Promise对象来执行它,并在将来某个时刻获得成功或失败的结果:
从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。
Promise的构造函数只接收一个函数作为参数,这个函数有两个回调函数作参数:这两个回调函数分别是resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。
var p = new Promise(test)
then 方法
then 方法接收两个函数(这个两个函数只能分别有一个参数)作为参数,第一个参数函数是 Promise 执行成功时的回调也就是上面resolve(e)时调用这个函数,e作为参数传递,第二个参数函数是 Promise 执行失败时的回调也就是上面reject(e)时调用这个函数,e作为参数传递,两个函数只会有一个被调用。
then 方法将返回一个 resolved 或 rejected 状态的 Promise 对象用于链式调用,且 Promise 对象的值就是这个返回值。
var a=function(e){document.write("<h1>"+e+"<\/h1>")};//定义返回后的执行函数
var b=function(e){document.write("<h1>"+e+"<\/h1>")};//定义返回失败后的执行函数
p.then(a,b)
在上面的代码中,我们执行了一个异步操作,也就是等待网络返回后,输出“执行完成”,并且调用resolve方法也就a函数。
注意!Promise我只要new了一个对象,函数会执先行了,取回的结果等待then方法调用,这是需要注意的一个细节。所以我们用Promise的时候一般是包在一个函数中,在需要的时候去运行这个函数,如:
function p_postreq(url, data) {
var p = new Promise(function (resolve, reject) {
//做一些异步操作,提交数据
wx.request({
url: rootDocment + url,
data: data,
method: 'post',
header: {
"Content-Type": 'application/x-www-form-urlencoded;charset=utf-8'
},
success: function (res) {
resolve(res.data)
},
fail: function () {
reject(false)
}
})
});
return p;
}
Promise 状态
状态的特点
Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。
Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。
Promise还可以做更多的事情,比如,有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。
要串行执行这样的异步任务,不用Promise需要写一层一层的嵌套代码。有了Promise,我们只需要简单地写:
job1.then(job2).then(job3).catch(function(error) {
// 处理前两个回调函数的错误
});
其中,job1、job2和job3都是Promise对象。
Promise.prototype.catch方法:捕捉错误
Promise.prototype.catch 方法是 Promise.prototype.then(null, rejection) 的别名,用于指定发生错误时的回调函数。
Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。
所以可以将catch写在串式调用的最后
除了串行执行若干异步任务外,Promise还可以并行执行异步任务。
试想一个页面聊天系统,我们需要从两个不同的URL分别获得用户的个人信息和好友列表,这两个任务是可以并行执行的,用Promise.all()实现如下:
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});
执行后等待所有任务完成后以数组形式返回Array: [‘P1’, ‘P2’]
有些时候,多个异步任务是为了容错。比如,同时向两个URL读取用户的个人信息,只需要获得先返回的结果即可。这种情况下,用Promise.race()实现:
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, ‘P1’);
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, ‘P2’);
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // ‘P1’
});
由于p1执行较快,Promise的then()将获得结果’P1’。p2仍在继续执行,但执行结果将被丢弃。