Promise基础用法
Promise 对象是一个代办对象,被代办的值在Promise对象建立时多是未知的。
它许可你为异步操纵的胜利和失利离别绑定响应的处置惩罚要领(handlers)。 这让异步要领能够像同步要领那样返回值,但并非马上返回终究实行效果,而是一个能代表将来涌现的效果的promise对象
一个 Promise有以下几种状况:
pending: 初始状况,既不是胜利,也不是失利状况。
fulfilled: 意味着操纵胜利完成。
rejected: 意味着操纵失利。
pending 状况的 Promise 对象能够触发fulfilled 状况并通报一个值给响应的状况处置惩罚要领,也能够触发失利状况(rejected)并通报失利信息。当个中任一种状况涌现时,Promise 对象的 then 要领绑定的处置惩罚要领(handlers )就会被挪用(then要领包括两个参数:onfulfilled 和 onrejected,它们都是 Function 范例。当Promise状况为fulfilled时,挪用 then 的 onfulfilled 要领,当Promise状况为rejected时,挪用 then 的 onrejected 要领, 所以在异步操纵的完成和绑定处置惩罚要领之间不存在合作)。
由于 Promise.prototype.then 和 Promise.prototype.catch 要领返回promise 对象, 所以它们能够被链式挪用。
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
promise1.then(function(value) {
console.log(value);
// expected output: "foo"
});
console.log(promise1);
// expected output: [object Promise]
Promise/A+
然后我们来相识一下Promise范例
Promises/A+范例(英文版)
Promises/A+范例(中文版)
Promise的完成
- Promise是经由过程new建立的,能够经由过程组织函数形式或者是ES6的class来完成,这儿挑选组织函数的体式格局来完成Promise,起首先完成一个浅易版本的Promise。
function Promise(exector) {
var _this = this
this.status = 'pending'
this.value = undefined
try {
exector(resolve, reject)
}catch(e) {
reject(e)
}
function resolve(value) {
if(_this.status === 'pending') {
_this.status = 'fulfilled'
_this.value = value
}
}
function reject(value) {
if(_this.status === 'pending') {
_this.status = 'rejected'
_this.value = value
}
}
}
Promise.prototype.then = function(resolveCallback, rejectCallback) {
if(this.status === 'fulfilled') {
resolve(this.value)
}
if(this.status === 'rejected') {
reject(this.value)
}
}
new Promise((resolve, reject)=> {
resolve('1')
}).then((data)=> {
console.log('resolve' + data)
}, (data)=> {
console.log('reject' + data)
}) //resolve1
new Promise((resolve, reject)=> {
setTimeout(()=> {
resolve('1')
}, 1000)
}).then((data)=> {
console.log('resolve' + data)
}, (data)=> {
console.log('reject' + data)
}) //没法一般输出
上面这个promise中resolve和reject在同步的状况下都能一般输出,然则如今却不支撑异步,由于在异步的时刻挪用then的时刻状况照样’pending’,所以resolve/reject并不能准期实行。
这个时刻就须要一个寄存后续挪用事宜的数组,当异步函数实行终了后再实行数组中的函数。
革新后异步要领能够一般运转:
function Promise(exector) {
var _this = this
this.status = 'pending'
this.value = undefined
this.resolveList = []
this.rejectList = []
try {
exector(resolve, reject)
}catch(e) {
reject(e)
}
function resolve(value) {
if(_this.status === 'pending') {
_this.status = 'fulfilled'
_this.value = value
_this.resolveList.forEach(item=> {
item(_this.value)
_this.resolveList.shift()
})
}
}
function reject(value) {
if(_this.status === 'pending') {
_this.status = 'rejected'
_this.value = value
_this.rejectList.forEach(item=> {
item(_this.value)
_this.rejectList.shift()
})
}
}
}
Promise.prototype.then = function(resolveCallback, rejectCallback) {
if(this.status === 'fulfilled') {
resolve(this.value)
}
if(this.status === 'rejected') {
reject(this.value)
}
if(this.status === 'pending') {
this.resolveList.push(resolveCallback)
this.rejectList.push(rejectCallback)
}
}
new Promise((resolve, reject)=> {
setTimeout(()=> {
resolve('1')
}, 1000)
}).then((data)=> {
console.log('resolve' + data)
}, (data)=> {
console.log('reject' + data)
})
链式挪用
我们能够注重到Promise是能够链式挪用的,这就须要then的要领返回一个Promise对象。
下面是一个链式挪用的简朴例子:
let promise = new Promise((resolve, reject)=> {
resolve(666)
})
promise.then(data=> {
console.log(data)
return data + 1
}).then(data=> {
console.log(data)
})
//666
//667
在Promise链中返回Promise:
let promise1 = new Promise((resolve, reject)=> {
resolve(666)
})
let promise2 = new Promise((resolve, reject)=> {
resolve(999)
})
promise1.then(data=> {
console.log(data)
return promise2
}).then(data=> {
console.log(data)
})
//666
//999
关于这类写法须要注重的是,第二个完成处置惩罚顺序被添加到第三个promise而不是return的promise2,上面的例子等价于:
let promise1 = new Promise((resolve, reject)=> {
resolve(666)
})
let promise2 = new Promise((resolve, reject)=> {
resolve(999)
})
let promise3 = promise1.then(data=> {
console.log(data)
return promise2
})
promise3.then(data=> {
console.log(data)
})
//666
//999
当异步的时刻挪用then函数的时刻状况为pending,这个时刻一样须要返回一个promise轻易后续的链式挪用。
所以修改成链式挪用后的代码为:
function Promise(exector) {
var _this = this
this.status = 'pending'
this.value = undefined
this.resolveList = []
this.rejectList = []
try {
exector(resolve, reject)
}catch(e) {
reject(e)
}
function resolve(value) {
if(_this.status === 'pending') {
_this.status = 'fulfilled'
_this.value = value
_this.resolveList.forEach(item=> {
item(_this.value)
_this.resolveList.shift()
})
}
}
function reject(value) {
if(_this.status === 'pending') {
_this.status = 'rejected'
_this.value = value
_this.rejectList.forEach(item=> {
item(_this.value)
_this.rejectList.shift()
})
}
}
}
Promise.prototype.then = function(resolveCallback, rejectCallback) {
var _this = this
if(this.status === 'fulfilled') {
return new Promise((resolve, reject)=> {
var result = resolveCallback(_this.value)
if(result instanceof Promise) {
result.then(resolve, reject)
}else {
resolve(result)
}
})
}
if(this.status === 'rejected') {
return new Promise((resolve, reject)=> {
var result = rejectCallback(_this.value)
if(result instanceof Promise) {
result.then(resolve, reject)
}else {
reject(result)
}
})
}
if(this.status === 'pending') {
return new Promise((resolve, reject)=> {
_this.resolveList.push(function() {
var result = resolveCallback(_this.value)
if(result instanceof Promise) {
result.then(resolve, reject)
}else {
resolve(result)
}
})
_this.rejectList.push(function() {
var result = rejectCallback(_this.value)
if(result instanceof Promise) {
result.then(resolve, reject)
}else {
reject(result)
}
})
})
}
}
new Promise((resolve, reject)=> {
resolve(666)
}).then((data)=> {
console.log('resolve1:' + data)
return 999
}).then((data)=> {
console.log('resolve2:' + data)
})
//resolve1: 666
//resolve2: 999
new Promise((resolve, reject)=> {
resolve(666)
}).then((data)=> {
console.log('resolve1:' + data)
return new Promise((resolve, reject)=> {
resolve(999)
})
}).then((data)=> {
console.log('resolve2:' + data)
})
//resolve1: 666
//resolve2: 999
基础的功用已完成,下面最先完成Promise的all,race,resolve,reject要领,链式挪用部份思绪自创Promise/A+范例的完成
Promise.all()
该要领只接收一个有多个受监听的Promise的可迭代对象(比方数组),只要当可迭代对中所有Promise都被处理后才会返回resolve,假如参数中 promise 有一个失利,此实例回调失利(reject),失利缘由的是第一个失利 promise 的效果。
Promise.all = function(iterable) {
return new Promise((resolve, reject) => {
let result = []
for(const item of iterable) {
item.then(data => {
result.push(data)
}, reason=> {
result = reason
return
})
}
resolve(result)
})
}
//下面是测试用例
let p1 = new Promise((resolve, reject) => {
resolve(666)
})
let p2 = new Promise((resolve, reject) => {
resolve(888)
})
let p3 = new Promise((resolve, reject) => {
resolve(999)
})
let p6 = new Promise((resolve, reject) => {
reject(222)
})
let p4 = Promise.all([p1, p2, p3])
p4.then(data => {
console.log(data)
})
//[666, 888, 999]
let p7 = Promise.all([p1, p3, p6])
p7.then(data => {
console.log(data)
})
//222
Promise.race()
Promise.race(iterable) 要领返回一个 promise,一旦迭代器中的某个promise处理或谢绝,返回的 promise就会处理或谢绝。
Promise.race = function(iterable) {
return new Promise((resolve, reject) => {
for(const item of iterable) {
item.then(data => {
resolve(data)
}, reason=> {
reject(reson)
})
}
})
}
//测试用例
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([p1, p2]).then(function(value) {
console.log(value);
// Both resolve, but promise2 is faster
});
//two
Promise.resolve()
Promise.resolve = function(data) {
return new Promise((resolve, reject) => {
resolve(data)
})
}
//测试用例
var p1 = Promise.resolve(123);
p1.then(function(value) {
console.log(value);
});
//123
Promise.reject()
Promise.reject(reason)要领返回一个带有谢绝缘由reason参数的Promise对象。
Promise.resolve = function(data) {
return new Promise((resolve, reject) => {
reject(data)
})
}