promise

promise是什么?

1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列

异步操作的常见语法

  1. 事件监听
document.getElementById('#start').addEventListener('click', start, false);
function start() {
  // 响应事件,进行相应的操作
}
// jquery on 监听
$('#start').on('click', start)

2.回调

// 比较常见的有ajax
$.ajax('http://www.wyunfei.com/', {
 success (res) {
   // 这里可以监听res返回的数据做回调逻辑的处理
 }
})

// 或者在页面加载完毕后回调
$(function() {
 // 页面结构加载完成,做回调逻辑处理
})

promise的基本用法

  • then中成功失败的执行

    // resolve代表成功 reject失败 都是一个函数
    
    let p = new Promise(function(reslove,reject){
    
        //reslove('成功')  //状态由等待变为成功,传的参数作为then函数中成功函数的实参
    
        reject('失败')  //状态由等待变为失败,传的参数作为then函数中失败函数的实参
    
    })
    
    //then中有2个参数,第一个参数是状态变为成功后应该执行的回调函数,第二个参数是状态变为失败后应该执行的回调函数。
    
    p.then((data)=>{
    
        console.log('成功'+data)
    
    },(err)=>{
    
        console.log('失败'+err)
    
    })
    

    Promise承诺:默认情况下是等待状态pending,如果有一天状态转变为成功就成功了,如果状态变成失败就失败了。状态一旦改变了就不能再改变了。

  • 如果then中返回了一个promise 会将promise的结果继续传给第二then中(如果结果是将状态改成成功就走下一个then的成功回调,状态改为失败就走下一个then的失败回调)

    function read( content ) {
        return new Promise(function( reslove,reject ) {
            setTimeout(function(){
                    if(content>4){
                        resolve(content)
                    }else{
                        reject('小于4')
                    }
            },1000)
        })
    }
    
    read(1).then(( data )=>{
        console.log(data)
    },( err )=>{
        console.log(err) //小于4
        return read(2) //将状态改为了失败
    })
    .then(( data )=>{
        console.log('data',data)
    },( err )=>{
        console.log(err) //小于4
    })
    
  • 第一个then不管是走成功还是失败的回到函数,只要返回一个普通值(不抛出错误或者返回promise),都会执行下一个then的成功的回调。

    let p = new Promise(function(reslove,reject){
        reject('失败1')
    })
    
    p.then((data)=>{
        console.log('成功'+data)
    },(err)=>{
        console.log('失败'+err) //失败失败1
    })
    .then((data)=>{
        console.log('成功1'+data) //成功1undefined
    },(err)=>{
        console.log('失败1'+err)
    })
    
    eg:抛出错误执行下一个then的失败
    
    let p = new Promise(function(reslove,reject){
        reject('失败1')
    })
    
    p.then((data)=>{
        console.log('成功'+data)
    },(err)=>{
        console.log('失败'+err) //失败失败1
    })
    .then((data)=>{
        console.log('成功1'+data) //成功1undefined
        throw Error('下一个失败')
    },(err)=>{
        console.log('失败1'+err)
    })
    .then((data)=>{
        console.log('成功2'+data)
    },(err)=>{
        console.log('失败2'+err) //失败2Error: 下一个失败
    })
    
  • catch的用法

    catch可以实现错误的捕获 一般写在最后,如果上面有自己的err会走自己的error。如果没有写就会走到catch

    let p = new Promise(function(resolve,reject){
        reject('失败')
    });
    
    p.then((data)=>{
    
    },(err)=>{
        throw Error('错误')
    })
    .then((data)=>{
    
    },(err)=>{
        console.log(err+'自己的err') //走自己的(输出:Error: 错误自己的err)
        throw Error('错误自己抛出的')
    })
    .then((data)=>{
    //没有自己的失败处理函数,走catch
    }).catch(e=>{
        console.log(e+'公共的err') //输出:Error: 错误自己抛出的公共的err
    })
    
  • all的用法

    Promise.all方法执行后返回的依旧是promise, all两个全成功才表示成功 。

    function read(content) {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                resolve(content)
            }, 1000)
        })
    }
    
    let result = Promise.all([read(1), read(2)]);
    result.then((data) => {
        console.log(data) //[ 1, 2 ]
    })
    

    有了all,就可以并行执行多个异步操作,并且在一个回调中处理所有的返回数据。返回的数据与传的参数数组的顺序是一样的。

  • race的用法

    如果先成功了那就成功了, 如果先失败了那就失败了

    function read(content) {
        return new Promise(function (resolve, reject) {
            setTimeout(function () {
                if(content>4){
                    resolve(content)
                }else{
                    reject(content)
                }
            }, 1000*content)
        })
    }
    
    let result = Promise.all([read(5), read(2)]);
    result.then((data) => {
        console.log('成功'+data)
    },(err)=>{
        console.log('失败'+err) //失败2
    })
    
  • finally()用法

    finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

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

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

    下面是一个例子,服务器使用 Promise 处理请求,然后使用finally方法关掉服务器。

    server.listen(port)
      .then(function () {
        // ...
      })
      .finally(server.stop);
    

    finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

    finally本质上是then方法的特例。

    promise
    .finally(() => {
      // 语句
    });
    
    // 等同于
    promise
    .then(
      result => {
        // 语句
        return result;
      },
      error => {
        // 语句
        throw error;
      }
    );
    

    上面代码中,如果不使用finally方法,同样的语句需要为成功和失败两种情况各写一次。有了finally方法,则只需要写一次。

    它的实现也很简单。

    Promise.prototype.finally = function (callback) {
      let P = this.constructor;
      return this.then(
        value  => P.resolve(callback()).then(() => value),
        reason => P.resolve(callback()).then(() => { throw reason })
      );
    };
    

    上面代码中,不管前面的 Promise 是fulfilled还是rejected,都会执行回调函数callback

    从上面的实现还可以看到,finally方法总是会返回原来的值。

    // resolve 的值是 undefined
    Promise.resolve(2).then(() => {}, () => {})
    
    // resolve 的值是 2
    Promise.resolve(2).finally(() => {})
    
    // reject 的值是 undefined
    Promise.reject(3).then(() => {}, () => {})
    
    // reject 的值是 3
    Promise.reject(3).finally(() => {})
    
  • reject()

    Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

    const p = Promise.reject('出错了');
    // 等同于
    const p = new Promise((resolve, reject) => reject('出错了'))
    
    p.then(null, function (s) {
      console.log(s)
    });
    // 出错了
    
    

    上面代码生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行。

    注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。

    const thenable = {
      then(resolve, reject) {
        reject('出错了');
      }
    };
    
    Promise.reject(thenable)
    .catch(e => {
      console.log(e === thenable)
    })
    

    上面代码中,Promise.reject方法的参数是一个thenable对象,执行以后,后面catch方法的参数不是reject抛出的“出错了”这个字符串,而是thenable对象。

  • promise的静态方法

    resolve:
    Promise.resolve([1,2,3]).then(function(data){
        console.log(data); //[1,2,3]
    });
    
    reject:
    Promise.reject([1,2,3]).then(null,function(err){
        console.log('err',err) //err [ 1, 2, 3 ]
    });

你可能感兴趣的:(promise)