Promise对象是一种异步编程的解决方案,比传统的解决方案——会掉函数和事宜——更合理和壮大。
Promise有三种状况:pending(举行中)、Resolved(Fulfilled,已完成)和Rejected(已失利);而且状况一旦转变,就不会再发作转变,Promise对象的状况只需两种能够:从Pending变成Resolved和从Pending变成Rejected。只需这两种状况发作了,状况就凝结了,不会再变了。Promise有一些瑕玷,就是没法作废,一旦新建它就会实行,没法半途作废;其次假如不设置回调函数,Promise内部抛出的毛病,不会回响反映到外部;第三Pending状况时,没法得知现在希望到哪个阶段。
基础用法
Promise组织函数接收一个函数作为参数,该函数参数分别是resolve和reject要领。假如胜利,则用resolve将Promise的状况改成胜利,即从Pending变成resolved;假如异步失利,则从Pending改成rejected。
基础用法
var promise = new Promise(function(resolve, reject){
if(/*异步操纵胜利*/){
resolve(value);
} else{
reject(error);
}
});
promise.then(function(value){
//success
}, function(value){
//failure
});
一个简朴有用的例子
function timeout(ms){
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
timeout(100).then(()=>{
console.log('done');
})
假如用Promise对象完成Ajax操纵
var getJSON = function(url){
var promise = new Promise(function(resolve, reject){
var client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
function handler(){
if(this.status == 200){
resolve(this.response);
}else {
reject(new Error(this.statusText));
}
}
return promise;
})
}
getJSON("/posts.json").then(function(json){
console.log("Contents:" + json);
}, function(error){
console.error('出错了', error);
})
在resolve的要领参数除了正常值认为,还能够能是另一个Promise实例。
Promise的链式操纵:Promise.prototype.then
Promise.prototype.then返回的是一个新的Promise对象,因而能够写成链式的。
getJSON("/posts.json").then(function(json){
return json.post;
}).then(function(){
//proceed
})
上面的代码指定了两个回调函数,第一个回调函数完成今后,会将效果作为参数传入到第二个回调函数。
假如第一个回调函数返回的是Promise对象,如许后一个函数挪用就将守候该Promise对象有了运转效果,才会进一步挪用。
getJSON("/post/1.json").then(function(post){
return getJSON(post.commentURL);
}).then(function(comments){
//对comments举行处置惩罚
})
捕捉毛病:Promise.prototype.catch要领
Promise.prototype.catch实际上是对Promise.prototype.then(null, rejection)的挪用,用于指定发作毛病时的回调函数。
Promise.prototype.catch 对毛病具有“冒泡”性子,会一向向后通报,直到被捕捉,也就是错我老是被下一个catch语句捕捉。
getJSON("/post/1.json").then(function(post) {
return getJSON(post.commentURL);
}).then(function(comments) {
// some code
}).catch(function(error) {
// 处置惩罚前两个回调函数的毛病
});
Promise.all要领
var p = Promise.all([p1,p2,p3]);
这个要领接收一个数组作为参数,p1,p2,p3都是Promise对象的实例。p的终究状况取决于参数对象数组的状况,上例中就是p1,p2,p3来决议的。假如这三个都是fulfilled,那末p的状况就是fulfilled;假如p1,p2,p3中有一个是rejected,p的状况就是rejected.那末p的状况就是reject,会通报给p的回调函数。
// 天生一个Promise对象的数组
var promises = [2, 3, 5, 7, 11, 13].map(function(id){
return getJSON("/post/" + id + ".json");
});
Promise.all(promises).then(function(posts) {
// ...
}).catch(function(reason){
// ...
});
Promise.resolve要领,Promise.reject要领
将现有对象转我Promise对象,Promise.resolve要领就起到这个作用。
var jsPromise = Promise.resolve($.ajax('/whatever.json'));
上面jQuery天生defferred对象,转为一个新的ES6的Promise对象。
假如Promise.resolve要领的参数,不具有then要领的对象(又称thenable对象),则返回一个新的Promise对象,且他的状况为fulfilled.
var p = Promise.resolve('Hello');
p.then(function(s){
console.log(s)
})
//Hello
上面天生一个新的Promise对象的实例p,它的状况为fulfilled。
Promise.reject(reason)要领也会返回一个新的Promise实例,该实例的状况为rejected,Promise.reject要领的参数reason,会被通报给实例的回调函数。
async函数
async函数是用来庖代回调函数的另一种要领。只需函数之前加上async的关键字,就表明该函数内部有异步操纵。该异步操纵返回一个Promise对象,前面用await关键字说明。当函数实行的时刻,一旦碰到await就立马返回,等接触到异步操纵完成,再接着实行函数体内背面的语句。
async function getStockPrice(symbol, currency) {
let price = await getStockPrice(symbol);
return convert(price, currency);
}
函数前面加了一个async表明该函数将返回一个Promise对象,挪用该函数时,碰到await关键字,马上返回背面的表达式发生的Promise对象,不再实行函数体背面的语句。等getStockPrice完成,在自动回到函数体内,实行剩下的语句。
function timeout(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncValue(value) {
await timeout(50);
return value;
}
上面代码中,asyncValue函数前面有async关键字,表明函数体内有异步操纵。实行的时刻,碰到await语句就会先返回,比及timeout函数实行终了,再返回value。