Promise对象
前言
应用场景:需要同步的时候使用,即语句运行需要有先后顺序的时候。
同步: 想了解同步和异步的点此
初识Promise:
可以看到Promise的实例p有的porto和属性
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined
既然是对象,那通常都就构造方法
Promise对象的构造方法接受一个方法(函数),方法有两个参数,形状如下:
let p=new Promise((resolve, reject) => {})
既然是对象,那通常都有属性
Promise其中一个属性叫 PromiseState(状态)
它的状态有三种:
- pending(准备中,待解决);
- fulfilled(已成功,成功解决)
- rejected(拒绝,没有成功解决)
Promise的状态可以通过调用resolve()
使其变成 fulfilled, reject()
使其变成 rejected,谁都没调用就是 pending。形状如下:
let p=new Promise((resolve, reject) => {
if(a+b==1){
resolve()//使其变成 fulfilled
}
else{
reject()//使其变成 rejected
}
})
Promise的状态一旦改变就不能再变了,如果调用了resolve(),再调用reject(),也不能使其从 fulfilled变到rejected,只能永远是fulfilled !!
Promise其中一个属性叫 PromiseResult(结果)
它是通过调用resolve('参数')
和reject('参数')
,传入的参数是什么,其结果就是什么。 形状如下:
let p = new Promise((resolve, reject) => {
resolve('我来自resolve');
})
console.log(p)
既然是对象,那通常都有方法
最常用的方法是then()
;
- 该方法有两个参数
- 两个参数都是函数
- 返回值是Promise对象 形状如下:
let p = new Promise((resolve, reject) => {
resolve('我来自resolve');//p的状态是fulfilled
//reject()
})
p.then(()=>{console.log('当p的状态是fulfilled时,执行')},()=>{console.log('当p的状态是rejected时,执行')})
then()
方法如何获取Promise的值呢?
- then(()=>{},()=>{})方法中的两个参数(函数),第一个参数获取Promise中调用的resolve('参数')中的参数
- then(()=>{},()=>{})方法中的两个参数(函数),第二个参数获取Promise中调用的reject('参数')中的参数
let p = new Promise((resolve, reject) => {
resolve('我强无敌,成功了');//p的状态是fulfilled
//reject('我太菜了,失败了')
})
p.then((value)=>{console.log(value)},(reason)=>{console.log(reason)})//第二个函数不会执行
let p = new Promise((resolve, reject) => {
reject('我太菜了,失败了')//p的状态是rejected
})
p.then((value)=>{console.log('12313')},(reason)=>{console.log(reason)})//第一个函数不会执行
如何理解这个现象?
Promise对象中调用的resolve('参数')
和reject('参数')
,其实是then(()=>{},()=>{})
参数的一个和第二个函数,即resolve和reject函数定义在then()
中,调用在Promise中。
由于then()返回的还是Promise,所以then()后面还可以再接then(),如此套娃下去,就可以完成你想要的同步步骤。
(注意:要再then()方法中的一个函数中使用return;使其返回值Promise的状态为fulfilled)
形状如下:
let p = new Promise((resolve, reject) => {
resolve('我强无敌,成功了');//p的状态是fulfilled
//reject('我太菜了,失败了')
})
p.then((value)=>{console.log(value);return '1234'},()=>{console.log('kkkk')})
.then((value)=>{console.log(value)},()=>{})
不要想着直接把Promise中的结果单独提出来,那是不可能的,Promise中的结果只能通过then()方法来使用
Promise的实际用例(忽略上下文,只是一个片段,百度翻译的ajax请求,有些操作需要请求完成才能继续操作)
function translation(uquery,ufrom,uto) {//返回的是Promise对象
return new Promise((resolve, reject) => {
let salt = (new Date).getTime();
let query = uquery;
// 多个query可以用\n连接 如 query='apple\norange\nbanana\npear'
let from = ufrom;
let to = uto;
let str1 = appid + query + salt + key;
let sign = window.MD5(str1);//签名
$.ajax({
url: '//api.fanyi.baidu.com/api/trans/vip/translate/non-https',
type: 'get',
dataType: 'jsonp',
async: false,
data: {
q: query,
appid: appid,
salt: salt,
from: from,
to: to,
sign: sign
},
success: function (data) {
if (data != null) {
resolve(data.trans_result[0].dst);//百度翻译返回的结果
}
}
});
})
}
translation(query,'zh','en').then(value =>
{let event = document.createEvent('Event')
event.initEvent('input', true, true);
$('.chat-input.border-box').val(value);
$('.chat-input.border-box')[0].dispatchEvent(event);
console.log(value);}).then(()=>
{$('.bl-button.live-skin-highlight-button-bg.bl-button--primary.bl-button--small').click();});