Promise对象的理解和使用

779 阅读3分钟

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();});