Promise简介

131 阅读3分钟

什么是Promise?

​ Promise是ES6中新出现的方便于解决异步编程的对象。他的编写方式相对于之前的异步编程方式更简洁,易懂,可维护行高。

为什么会出现Promise

​ 之前一般都是使用回调函数的方式作为异步编程

function sendRequest(){
  ajax((请求)=>{
    //处理逻辑
    //
    //。。
  })
}

上面是ajax异步请求的接口,这样看起来没有问题,那么当你有很多关联的请求

function sendRequest(){
	ajax((请求1)=>{
    //处理逻辑
    ajax((请求2=>{
      //处理逻辑
      ajax((请求3=>{
        //处理逻辑
         ajax((请求4=>{
        	//处理逻辑
        })
      })
    })
  })
}

上面展示的就是典型的回调地狱。这种代码看着就让人犯头疼

  • 代码臃肿。
  • 可维护性差。
  • 耦合度过高。
  • 代码复用性差。
  • 容易滋生 bug,且不好调试排错。
  • 只能在回调里处理异常。

而Promise就很好的解决了这种问题。

如何使用Promise

简单使用

Promise没有复杂的回调函数方式,而是采用链式调用,这样看起来就比较简单,易读

function promiseRun(){
  new Promise(ajax()=>{
    //处理逻辑
  }).then(ajax()=>{
    //处理逻辑
  }).then(ajax()=>{
    //处理逻辑
  }).then(ajax()=>{
    //处理逻辑
  }).then(ajax()=>{
    //处理逻辑
  })
}

每次使用构造函数new Promise( function),会先执行function,然后执行外面的逻辑,等待function中得到返回值后,开始处理then中的逻辑

常用API

constructor(executor(resolve,reject?))

​ 传入一个方法executor作为参数,而这个方法是一个以resolve和reject为参数,executor在new Promise时就立即执行,executor处理成功在他的内部调用resolve,并将result作为参数,若是失败或者错误;调用reject方法,并将错误原因作为参数

function promiseRun(){
  function testPromise(resolve, reject) {
    console.log('start new Promise...');
    const timeOut = new Date().getMilliseconds();
    setTimeout(function () {
        if (timeOut < 500)
        {
            console.log('success : ' + timeOut);
            resolve('200 OK');
        }
        else {
            console.log('error : ' + timeOut);
            reject('500 failed');
        }
    }, timeOut)
  }
  new Promise(testPromise);
  console.log('end')
}

>start new Promise...
>end
>error : 518
OR
>start new Promise...
>end
>success : 321

then(onfulfilled(result?),onreject(reason?)?)

​ onfulfilled成功后调用的方法,参数是成功后的返回值result,就是在testPromise中调用resolve传入的参数;onreject失败后调用的方法,参数是失败的原因reason,在testPromise中调用reject传入的参数,或则系统错误

function promiseRun(){
  new Promise(testPromise).then(result=>console.log(result),reason=>console.log(reason))
}

>start new Promise...
>end
>error : 518
>500 failed
OR
>start new Promise...
>end
>success : 321
>200 OK

catch(onrejected(reason?)?)

​ 捕获其上方调用的错误,而catch和then中第二个参数没有区别

function promiseRun(){
  new Promise(testPromise)
    	.then(()=>new Promise(testPromise),reason=>console.log(reason)) //这里的then只能执行其中一个回调函数
        .then(()=>new Promise(testPromise))
        .then(()=>new Promise(testPromise))
        .catch((reason) => console.log(reason));
}

all(function[])

​ 多个 Promise 任务同时执行。如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。不过当一个Promise任务错误了,也不影响其他任务执行

function promiseRun(){
	Promise.all( [new Promise(testPromise), new Promise(testPromise), new Promise(testPromise), new Promise(testPromise)])
        .then(results=> console.log(results),reason => console.log(reason))//最终打印‘500 failed’ OR ‘["200 OK", "200 OK", "200 OK", "200 OK"]’
}

race()

​ 执行方式如同名字一样,赛跑;多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败。也不影响其他任务的执行,只是不接收他们的结果或是错误

function promiseRun(){
	Promise.race( [new Promise(testPromise), new Promise(testPromise), new Promise(testPromise), new Promise(testPromise)])
        .then(results=> console.log(results),reason => console.log(reason)) // 最中打印‘500 falied’ OR ‘200 OK’
}

参考

www.liaoxuefeng.com/wiki/102291…

developer.mozilla.org/zh-CN/docs/…