promise

1 ,背景

Promise 是异步编程的一种解决方案,Promise 是一个对象,从它可以获取异步操作的消息

2,特点

(1)对象的状态不受外界影响。

Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。

只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态

(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。

Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected

只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)

3,缺点

(1)无法取消Promise,一旦新建它就会立即执行,无法中途取消。

(2)如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

(3)当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

4,用法

 1 基本用法

let p1 = () => {
      return new Promise((resolve, reject) => {
                console.log('3秒钟后,p1函数结束');
                setTimeout(() => {
                     //返回Promise
                    resolve(p2())
               }, 3000)
      })
};


let p2 = () => {
     return new Promise((resolve,reject)=> {
               console.log('p1结束,现在是第二个任务了!');
              resolve({key: 2, content: "第二个任务结束"})
     })
};


p1().then((res) => {
    console.log(res);
    p2().then((res2) => {
          console.log(res2);
         //返回Promise
        return new Promise((resolve ,reject)=> {
                console.log('开始第三个任务,这个任务是继续第二个的异步。');
                setTimeout(()=>reject({key:3,content:"第三个任务报错!"}),2000)
        })
   }).catch((error)=>console.log(error));
});

结果:

3秒钟后,p1函数结束   -------promise创建后立即执行

-----  console.log(res);

p1结束,现在是第二个任务了!

{key: 2, content: "第二个任务结束"}

 

------console.log(res2);

      p1结束,现在是第二个任务了!

      {key: 2, content: "第二个任务结束"}

    --------在resolve后调用catch无效,无法抛出错误,因为状态已经改变

     开始第三个任务,这个任务是继续第二个的异步

 

注意点: promise是个对象  一定要return出来, Promise对象上才有then、catch回调和  2个参数  resolve  rejecte

let promise = new Promise(function(resolve, reject) {
  console.log('Promise');
  resolve();
});

promise.then(function() {
  console.log('resolved.');
});

console.log('Hi!');

// Promise
// Hi!
// resolved

上面代码中,Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出

2 升级用法:

a  )Promise.prototype.then() 

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。这两个函数都是可选的,不一定要提供。它们都接受Promise对象传出的值作为参数。

采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

b )Promise.prototype.catch()

.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

c )  p=promise.all([a(),b()]).then().catch()  //必须一起执行且都成功,只返回第一个错误状态

Promise.all()只有在接受的所有promise实例全部是fulfilled才会走Promise.all([p1,p2,p3]).then()方法,
只要有其中一个promise实例是rejected,就会直接走catch方法--结束,并且catch中只会返回第一个变成rejected的promise的错误

(1)只有a,b的状态都变成fulfilledp的状态才会变成fulfilled,此时a,b的返回值组成一个数组,传递给p的回调函数。

(2)只要a,b之中有一个被rejected, p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

d)Promise.allSettled([a(),b()]).then().catch() //返回所有的请求状态  并确保请求结束

   获取所有入参的异步操作的所有结果,知道这些异步操作是否全部结束

const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);

const allSettledPromise = Promise.allSettled([resolved, rejected]);

allSettledPromise.then(function (results) {
  console.log(results);
});
// [
//    { status: 'fulfilled', value: 42 },
//    { status: 'rejected', reason: -1 }
// ]

e) p=promise.race([a(),b()]).then().catch() //谁跑的快用谁的值

Promise.race() 总是返回第一个结果值(resolved/reject)那样,这个方法返回的是第一个 成功的 值。

只要有其中一个promise实例是rejected,就会直接走catch方法--结束。并且catch中只会返回第一个变成rejected的promise的错误

   只要a,b之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

f) Promise.any([a(),b()]).then().catch()

只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

 

g)  Promise.prototype.finally()

 

promise.then(result => {···}).catch(error => {···}).finally(() => {···});

   不管promise最后的状态,在执行完thencatch指定的回调函数以后,都会执行finally方法指定的回调函数

 finally的回调函数不接受任何参数,方法里面的操作,是与状态无关的,不依赖于 Promise 的执行结果。

 

 

p就是一个promise对象 才有then方法

 

let p=new Promise((resolve,reject)=>{
         resolve('成功')
     })
p.then(resolve=>{
    console.log(resolve)
},reject=>{
    console.log(reject)
})

 


let p=function(){
     return new Promise((resolve,reject)=>{
               resolve('成功')
    })
}
p是个函数 不是个对象 p()才是一个对象(因为有return,返回出来promise对象)


p().then(resolve=>{
            console.log(resolve)
    },reject=>{
        console.log(reject)
})

 

 

var a=0;
let p1=function(){
     return new Promise((resolve,reject)=>{
          a++;
         resolve(a);

    })
}
let p2=function(){
     return new Promise((resolve,reject)=>{
           a+=2;
          resolve(a);

   })
}


let p3=function(){
return new Promise((resolve,reject)=>{
a+=3;
resolve(a);
})
}
p1().then(resolve=>{
console.log(resolve)
return p2();//这个return是为了后面的then

}).then(resolve=>{
console.log(resolve)
return p3();//这个return是为了后面的then

}).then(resolve=>{
console.log(resolve)

})
//136

posted @ 2021-01-05 10:55  青橙娃娃  阅读(114)  评论(0编辑  收藏  举报