一 什么是Promise
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
ES6将程序分为三种状态 pendding resolved rejected
pendding : 挂起(等待) 处于未决阶段,表示当前事情还处于挂起状态最终结果没有出现
resolved : 已处理 处于已决阶段,表现是事情已经出现了结果,这个结果是一个成功的结果,可以按照当前结果的正常逻辑顺序继续下去的结果
rejected : 已拒绝 处于已决阶段,表现是事情已经出现了结果,这个结果是一个未成功的结果,当前结果的并不能按照正常逻辑顺序继续下去的结果
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
实例:
先实例化一个Promise对象
const pro = new Promise((resolve, reject) => {
resolve("123")
})
pro.then(data => {
console.log(data)
}, err => {
console.log(err)
})
此时控制台输出的结果就是
我们再来看另外一种
const pro = new Promise((resolve, reject) => {
resolve("123")
reject('789')
})
pro.then(data => {
console.log(data)
}, err => {
console.log(err)
});
这个时候我们在下面写了一个reject我们再来看看结果:
仍然是123,那么这是为什么呢 因为resolve和reject函数只可以使用一个,如果使用多个,也只有第一个有用
上面说到了resolve和reject 现在我们就来说说这两个是什么
resolve
resolve是处理返回成功的结果 当结果成功后
先是方法被调用起来执行了promise,最后执行了promise的then方法,then方法是一个函数接受一个参数是接受resolve返回的数据这事就输出了‘要返回的数据可以任何数据例如接口返回数据’
这时候你应该有所领悟了,原来then里面的函数就跟我们平时的回调函数一个意思,能够在promiseClick这个异步任务执行完成之后被执行。这就是Promise的作用了,简单来讲,就是能把原来的回调写法分离出来,在异步操作执行完后,用链式调用的方式执行回调函数。
你可能会觉得在这个和写一个回调函数没有什么区别;那么,如果有多层回调该怎么办?如果callback也是一个异步操作,而且执行完后也需要有相应的回调函数,该怎么办呢?总不能再定义一个callback2,然后给callback传进去吧。而Promise的优势在于,可以在then方法中继续写Promise对象并返回,然后继续调用then来进行回调操作。
所以:精髓在于:Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多
比如写一个例子:
function mfc(kh, callback) {
return new Promise(resolve => {
console.log(`cxb接受${kh}`)
setTimeout(() => {
if (Math.random() > 0.3) {
resolve(true);
} else {
resolve(false);
}
}, 500)
})
}
let kh = ['1', '2', '3', '4', '5', '6'];
let pro;
for (let i = 0; i < kh.length; i++) {
if (i == 0) {
pro = mfc(kh[i]);
}
pro = pro.then(data => {
if (data === undefined) {
return;
} else if (data) {
console.log(`${kh[i]}成功`);
return undefined;
} else {
console.log(`${kh[i]}失败`);
return mfc(kh[i + 1])
}
})
}
reject
reject就是失败的时候的回调,他把promise的状态修改为rejected,这样我们在then中就能捕捉到,然后执行“失败”情况的回调。
function pro() {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
var num = Math.ceil(Math.random() * 20);
console.log('随机数生成的值:', num)
if (num <= 10) {
resolve(num);
} else {
reject('数字太于10了即将执行失败回调');
}
}, 2000);
})
return p
}
pro().then(
(data) => {
console.log('resolved成功回调');
console.log('成功回调接受的值:', data);
},
(reason, err) => {
console.log('rejected失败回调');
console.log('失败执行回调抛出失败原因:', reason);
}
);
pro().then(
(data) => {
console.log('resolved成功回调');
console.log('成功回调接受的值:', data);
},
(reason, err) => {
console.log('rejected失败回调');
console.log('失败执行回调抛出失败原因:', reason);
}
);
调用pro方法执行,2秒后获取到一个随机数,如果小于10,我们算成功,调用resolve修改Promise的状态为fullfiled。否则我们认为是“失败”了,调用reject并传递一个参数,作为失败的原因。并将状态改成rejected
运行pro并且在then中传了两个参数,这两个参数分别是两个函数,then方法可以接受两个参数,第一个对应resolve的回调,第二个对应reject的回调。(也就是说then方法中接受两个回调,一个成功的回调函数,一个失败的回调函数,并且能在回调函数中拿到成功的数据和失败的原因),所以我们能够分别拿到成功和失败传过来的数据就有以上的运行结果