关于Promise!你都搞懂了吗?

Promise简单来说就是一个容器,保存着某个未来才会结束得事件(通常为异步操作)得结果。从语法上来讲,Promise是一个对象,可以获取异步操作得消息;Promise提供了统一 得API,各种异步操作都可以用同样得方法进行处理。复制代码

1、 Promise对象有两大特点:

1)对象得状态不受外界得影响。Promise对象代表一个异步操作。有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。 Promise 对象的状态改变,只有两种可能:从 pending 变为 fulfilled 和从 pending 变为 rejected 。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对 Promise 对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。复制代码

2.Promise得缺点:

1)无法取消 Promise ,一旦新建它就会立即执行,无法中途取消;
2)如果不设置回调函数, Promise 内部抛出的错误,不会反应到外部。
3)当处于 pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。复制代码

3.Promise用法:

1)Promise对象是一个构造函数,用来生成Promise实例;

const KKBpromise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});复制代码

Promise 构造函数接受一个函数作为参数,该函数的两个参数分别是resolve 和reject 。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

resolve 函数的作用是,将 Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将 Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去.

Promise 实例生成以后,可以用 then方法分别指定resolved状态和 rejected状态的回调函数。 举个栗子:

KKBpromise.then(function(value) {
  // success
}, function(error) {
  // failure
});复制代码

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

function pros(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
  });
}
pros(100).then((value) => {
  console.log(value);
});复制代码

pros 方法返回一个 Promise 实例,表示一段时间以后才会发生的结果。过了指定的时间( ms 参数)以后, Promise 实例的状态变为 resolved ,就会触发 then 方法绑定的回调函数。

2)Promise新建后会立即执行。 举例说明:

let promise = new Promise(function(resolve, reject) {
  console.log('Pro');
  resolve();
});
promise.then(function() {
  console.log('resolved');
});
console.log('Hello Promise!');
// Pro
// Hello Promise!
// resolved复制代码

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

扫描二维码关注公众号,回复: 12133312 查看本文章

有时候在调用 resolve 或 reject 以后,Promise 的使命就完成了,后继操作应该放到 then 方法里面,而不应该直接写在 resolve 或 reject 的后面。所以,最好在它们前面加上 return 语句,这样就不会有意外。

new Promise((resolve, reject) => {
  return resolve(1);
  // 后面的语句不会执行
  console.log('接着执行');
})复制代码

4.Promise常用得API:

1)Promise.all()这个方法返回一个新的promise对象,该promise对象在所有的promise对象都成功的时候才会触发成功,一旦有任何一个里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含所有promise返回值的数组作为成功回调的返回值,顺序跟参数的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。

let kkb1 = new Promise((resolve, reject) => {
 resolve('成功了kkb1')
})

let kkb2 = new Promise((resolve, reject) => {
 resolve('成功了kkb2')
})

let kkb3 = Promse.reject('失败')


Promise.all([kkb1, kkb2])
 .then((result) => {
   console.log(result) //['成功了kkb1', '成功了kkb2']
 })
 .catch((error) => {
   console.log(error)
 })


Promise.all([kkb1,kkb3,kkb2])
 .then((result) => {
   console.log(result)
 })
 .catch((error) => {
   console.log(error) //  '失败'
 })复制代码

2)Promise.race的使用 race和all用法类似。Promse.race方法顾名思义就是赛跑的意思,意思就是说Promise.race([kkb1, kkb2, kkb3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

let kkb1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('kkb1')
  },1000)
})
 
let kkb2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('kkb2')
  }, 500)
})
 
 
Promise.race([kkb1, kb2])
  .then((result) => {
    console.log(result)
  }).catch((error) => {
    console.log(error)  //  打印出kkb2 因为它快
  })复制代码

猜你喜欢

转载自blog.51cto.com/15069732/2575865
今日推荐