美文网首页
Promise之我见

Promise之我见

作者: lzyup | 来源:发表于2018-07-26 20:14 被阅读0次

Promise之我见

1、Promise的含义

  • Promise是异步编程的一种解决方案,用来解决函数的嵌套,也就是传说中的回调地狱
  • Promise对象具有状态,分为两种状态变化
    • pendingfulfilled
    • pendingrejected
      这两种状态的变化任一个发生就定型了不会再发生改变。

2、Promise的基本用法

let p = new Promise((resolve, reject) => {
  // 做一些事情
  // 然后在某些条件下resolve,或者reject
  if (/* 条件随便写^_^ */) {
    resolve()
  } else {
    reject()
  }
})

p.then(() => {
    // 如果p的状态被resolve了,就进入这里
}, () => {
    // 如果p的状态被reject
})

这里解释一下,Promise构造函数接受一个函数作为参数,resolve和reject是这个函数的两个参数。

  • resolve函数的作用就是将Promise的状态从pendingfulfilled
  • reject函数的作用就是将Promise的状态 从pendingrejected
  • then方法是Promise状态发生改变的回调函数,该方法的第一个参数是resolve处理后状态发生变化的回调函数,第二参数是reject处理后状态发生变化的回调函数,需要强调的是 then方法返回的是一个新的Promise实例,不是原来那个Promise,所以可以采用链式的写法来避免回调地狱。

3、Promise链式调用

  • 案例分析一
下面分别是三个Promise
function testPromise1(){
    let p = new Promise(function(resolve,reject){
    setTimeout(function(){
        console.log("第一个Promise");
        resolve("数据111");
},1000)
});
return p;
}

function testPromise2(){
    let p = new Promise(function(resolve,reject){
    setTimeout(function(){
        console.log("第二个Promise");
        resolve("数据222");
},1000)
});
return p;
}

function testPromise3(){
    let p = new Promise(function(resolve,reject){
    setTimeout(function(){
        console.log("第三个Promise");
        resolve("数据333");
},1000)
});
return p;
}


接着链式调用
testPromise1()
    .then(function(data){
        console.log(data);
        return testPromise2();
})
.then(function(data){
    console.log(data);
    return testPromise3();
})
.then(function(data){
    console.log(data);
})

输出的结果为:
    第一个Promise
    数据111
    第二个Promise
    数据222
    第三个Promise
    数据333

不难发现,在每个then方法中都返回了一个新的Promise,通过调用新的Promisethen方法从而实现链式调用。

  • 案例分析二
Promise.resolve()
  .then(() => {
    return new Error('error!!!')
  })
  .then((res) => {
    console.log('then: ', res)
  })
  .catch((err) => {
    console.log('catch: ', err)
  })

输出的结果为
``
then: Error: error!!!
    at Promise.resolve.then (...)
    at ...
  • 这里指的关注的第一点是,then方法中return一个error对象并不会抛出错误,所以不会被后续的.catch捕获,需要改成下面中的一种
    • return Promise.reject(new Error('error!!!'))
    • throw new Error('error!!!')
  • then方法中返回任意一个非promise的值都会被包裹为Promise对象,即return new Error('error!!!')等价于return Promise.resolve(new Error('error!!!'))

4、 Promise.then

  • Promise实例具有then方法。
  • then方法有两个参数,第一个参数是resolve状态的回到函数,第二参数(可选)是reject状态的回调函数,看到这里有没有觉得这个then方法的参数很眼熟,对,你猜的没错,这不是跟Promise的构造函数的参数一样嘛,所以就有下面这一点。
  • then方法返回的是一个新的Promise实例(不是原来那个Promise实例了)。

5 、Promise.catch

  • Promise.catch方法是.then(null,rejection)的别名,用于指定发生错误时的回调函数。
// bad
promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  });

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

一般来说,第二种写法是好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。用Promise链式调用的时候也只用在最后加一个catch用来捕获错误即可。

6 、Promise.all的使用

Promise.all方法接受一个数组作为参数,包装成一个新的Promise实例。
例如

Promise
.all([testPromise1(),testPromise2(),testPromise3()])
.then(function(results){
})
  • 这里只有testPromise1()testPromise2()testPromise3()三个Promise的状态都从pendingfulfilled那么Promise.all的状态才会从pendingfulfilled
  • 这里只要testPromise1()testPromise2()testPromise3()中有一个状态变为reject那么Promise.all就会变成reject状态
  • 适用的场景主要是,可能你一个网络请求需要的一些参数依赖于不用的异步任务获取,等这些异步任务都完成,你拿到全部参数才能发这个网络请求。

7、 Promise.race的用法

  • Promise.all的区别在于,接受的数组参数里面,只要有一个Promise状态发生的变化,就能在Promise.allthen方法里面执行回调函数。

相关文章

网友评论

      本文标题:Promise之我见

      本文链接:https://www.haomeiwen.com/subject/nakimftx.html