Promise

124 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

什么是Promise

ES6中Promise对象是一个构造函数,因为Javascript是单线程的,为了解决异步编程,用promise来延迟计算和异步计算。

Promise的特点
  • 对象状态不收外界影响,只受异步结果控制promise的状态:pending、fulfilled、rejected(进行中、已成功、已失败)
  • 一旦状态改变,就不会再变。promise的状态只能由pending变为fulfilled或者pending变为rejected两种状态,且两种状态只能存在一个,一旦转变不能更改。
resolve和reject

当一个函数作为参数传入Promise中时,这个函数有两个参数分别为resolve和reject。

  • resolve:将promise的状态由pending变为fulfilled,并把结果作为参数传出去

  • reject:pending变为rejected,并把错误作为参数传出去

使用
  • 创建一个Promise

    let P = new Promise(function(reslove,reject){
        //异步
        setTimeout(function(resolve,reject){
            console.log('success')
        },1000)
    })
    
  • Promise中的then:可以接受两个参数,第一个是resolve的回调,第二个是reject的回调

    function fn1() {
        let P = new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log('fn1 success');
                resolve(111111)
            },1000)
    	});
        return P;
    }
    
    fn1()
    .then(function(data){
    	console.log(data)
    })
    
  • Promise中的catch:在then中执行resolve的回调错误时会在catch中把错误抛出,并继续执行代码

    function fn1() {
        let P = new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log('fn1 success');
                resolve(111111)
            },1000)
    	});
        return P;
    }
    
    fn1()
    .then(function(data){
    	console.log(data)
    })
    .catch(function(data){
      console.log(data)
    })
    
  • Promise.all:可以接受一个数组参数,在执行完所有异步之后再进入then,并把所有得到的值传到then中。

    function fn1() {
        let P = new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log('fn1 success');
                resolve(111111)
            },1000)
    	});
        return P;
    }
    function fn2() {
        let P = new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log('fn2 success');
                resolve(222222)
            },2000)
    	});
        return P;
    }
    
    Promise
    .all(fn1(),fn2())
    .then(function(data){
      console.log(data)
    })
    
解决了什么问题
  • 回调函数:当一个函数作为参数传到另一个函数当中,他并不会立即执行,而是是回头再调用的函数,那什么时候再调用呢?当满足一定的条件后函数才会被执行,这种函数被称为回调函数。

    setTimeout(()=>{
        console.log('I am the callback function');
    },5000)
    
  • 回调地狱:因为Javascript是单线程的,异步的代码不能一定按照顺序执行,为了让代码按照顺序执行,会在回调函数中套用回调函数,导致代码的可读性和维护性较差,这种形式被称为回调地狱。

    setTimeout(()=>{
        console.log(1)
        setTimeout(()=>{
            console.log(2)
            setTimeout(()=>{
                console.log(3)
            },1000)
        },2000)
    },3000)
    
  • 用promise改写

    function fn1() {
        let P = new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log('fn1 success');
                resolve(111111)
            },1000)
    	});
        return P;
    }
    function fn2() {
        let P = new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log('fn2 success');
                resolve(222222)
            },2000)
    	});
        return P;
    }
    function fn3() {
        let P = new Promise(function(resolve,reject){
            setTimeout(function(){
                console.log('fn3 success');
                resolve(333333)
            },3000)
    	});
        return P;
    }
    fn1()
    .then(function(data){
    	console.log(data)
        return fn2()
    })
    .then(function(data){
    	console.log(data)
        return fn3()
    })
    .then(function(data){
    	console.log(data)
    })