我我的以为Promise 函数跟 普罗米修斯很像,都是表明着处理将来的事情的先知。既然能处理将来的事情,那就表明着它拥有很是的能力,听我慢慢吹来呀~ 首先来看看官方的吹牛文档解释:ajax
所谓Promise,简单说就是一个容器,里面保存着某个将来才会结束的事件(一般是一个异步操做)的结果。从语法上说,Promise 是一个对象,从它能够获取异步操做的消息。Promise 提供统一的 API,各类异步操做均可以用一样的方法进行处理。json
你看没错吧,是否是很像一个先知能够处理将来的事情?既然是神仙确定是我们凡人管不了的,为啥管不了那?就体如今它三个内部状态上:api
对象的状态不受外界影响。Promise对象表明一个异步操做,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)只有异步操做的结果,能够决定当前是哪种状态,任何其余操做都没法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其余手段没法改变。数组
看见了吗,敲黑板划重点,神仙已经决定的东西就不能改变。并且一旦new Promise对象就不能取消,讲究~promise
那如何使用那?下面来看一个简单的例子:bash
const promise = new Promise (function(resolve, reject) { //这是先知啊,先知
if (/* 异步操做成功 */){
resolve(value); // resolve就是这事儿先知赞成了,你就干就完了
} else {
reject(error); // reject就是这事儿先知不一样意,白b扯了
}
});
复制代码
注意上面的事情其实有没有发生?没有,先知嘛预知将来的事情,何时发生那?固然先知赞成的时候也就是说状态变成resolved。只要一resolved 立刻就能够then了,划重点 敲黑板 then 就是这玩意。app
promise.then(function(value) {
// 妥妥的这个已经办了,下面你想咋地吧?能够连式操做无限then下去
}, function(error) {
// 失败了消停的把错误信息打出来把
console.log("错误信息:"+error)
});
复制代码
那么坑人的玩意来了,请看下面代码,谁先打印?异步
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
复制代码
上面代码中,Promise 新建后当即执行,因此首先输出的是Promise。而后,then方法指定的回调函数,将在当前脚本全部同步任务执行完才会执行,因此resolved最后输出。那么接下来这段 函数
概念吹完了,来看势力post
妥了,接下来看一个用Promise对象实现的 Ajax 操做的实例:
const getJSON = function(url) {
const promise = new Promise(function(resolve, reject){
const handler = function() {
if (this.readyState !== 4) {
return;
}
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handler;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
};
getJSON("/posts.json").then(function(json) {
console.log('Contents: ' + json);
}, function(error) {
console.error('出错了', error);
});
复制代码
是否是很简单,一点都不难,只是把ajax的操做流程放到了先知的内部,让先知帮你获取各类成功失败的状态!结合实际,咱们在工做中可能一次要请求好几个接口的数据,Promise提供了一个更加简单的方法
const p = Promise.all([p1, p2, p3]);
复制代码
很好理解,all 的参数表明这一个可执行的任务队列,只要里面有任务就能够往下执行,也就是我们访问的多个api集合组成的数组。
// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
return getJSON('/post/' + id + ".json"); //ID 做为参数 变成动态请求
});
Promise.all(promises).then(function (posts) {
// ...
}).catch(function(reason){
// ...
});
复制代码
还有一个相似 all的api Promise.race,Promise.race方法的参数与Promise.all方法同样,若是不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理
const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]);
p
.then(console.log)
.catch(console.error);
复制代码
上面代码中,若是 5 秒以内fetch方法没法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。
妥妥滴,既然到这里我估计你应该懂了,其实任何技术都不难,都能拆分红若干个简单点。任意简单的点组合起来就又复杂了,正所谓大道至简,相信万事万物都是简单的原理,怀着敬畏的心理去学习,终究会获得本身的收获。