一文带你了解promise

·  阅读 64

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

1,什么是promise?

1,抽象表达:promise是js中进行一步编程的新的解决方案(旧的是—纯回调函数)
2,具体表达
语法上讲:promise是一个构造函数,可以new创建一个 promise
功能上讲:promise对象用来封装一个异步操作并可以获取其结果
3,目的:解决回调地狱问题
注:promise 状态改变中,resolved为成功回调, reject失败回调;只有两种状态,且一个promise对象只能变一次;无论变为成功还是失败,都会有一个结果数据;成功的结果数据一个称为 value ,失败的结果数据一般称为 reason
4,promise 的基本使用

**

var  promise=new Promisefunction(){})
复制代码

注:这是一个异步操作,其中function 内部写的就是具体的异步操作

2,why—为什么用?

1,作用:指定回调函数的方式更加灵活

旧的:必须在启动异步任务前指定
promise:启动异步任务=>返回promise对象=>给promise对象绑定回调函数
注:promise的实例是一个异步操作,无法使用return把操作的结果返回给调用者,这时候,只能使用回调函数的形式,来把成功 或 失败的结果,返回给调用者;

2,promise 原型上的 .then 方法是预定为后面成功和失败的回调,成功的回调必须传,失败的回调可以不传
3,支持链式调用,可以解决回调地狱问题
4,async / await:回调地狱的终极解决方案

**

getFIiePath(path){
            var  promise= new Promise(function(resolve,reject){
                if (err) return reject ( err ){ }
                resolve(data){ }
            })
              return promise;
        },
getFIiePath(xxx_路径).then( succse( data){  } , fail(err ){  } )
复制代码

3,怎么用?

callback:这个只是表示他是一个回调函数的占位符,他只是作为一个参数,具体的形式,是看传的函数是什么 callback 只有两种形式:成功回调(第一个位置),失败回调(第二个位置)
1,上一个 .then 中,return 一个新的 promise 实例,可以继续用下一个 .then 来处理
2,promise 一旦出错,进行捕获,继续执行下去,否则,不会继续执行
3,如果不想前面的 promise 出错,操作被终止,可以为每个 promise 指定失败的回调捕捉

**

getFile("./files/1.txt")
        .then(function(data){
            console.log(data)
            return getFile("./files/2.txt")
        })
        .then(function(data){
            console.log(data)
            return getFile("./files/3.txt")
        })
        .then(function(data){
            console.log(data) 
        })
        .catch(function(err){  
       // catch 捕获 promise 中抛出的所有异常
            console.log(err)
        })
复制代码

注:出错类型在下面有补充说明,
4,promise 的工作流程\

promise.png

4,async和await — 异步函数

同步函数:立即执行,完全执行完了才结束,不会放入回调队列中
异步函数:不会立即执行,会放入回调队列中将来执行

1,普通函数 中使用 async关键字,就会变为异步函数,
2,异步函数中,return 后面默认被包裹了一层 Promise 对象,return关键字代替了 reslove 方法
3,异步函数中,使用 throw 关键字抛出程序异常,
4,调用异步函数再链式调用 .then方法,获取异步函数中执行结果
5,调用异步函数再链式调用 .catch方法,获取异步函数中错误信息

**

async function fn(){
      throw '发生了写错误'; // 当 throw 方法执行之后,后面的方法就不会继续执行
      return 123
 }
fn().then(function(data){
    console.log(data); // 123
}).catch((err)=>{
   console.log(err)
})
复制代码

await 关键字

1,await只能出现在async异步函数中
2,await Promise await后面只能写Promise对象,写其他的API不可以,
3,await 关键字可以暂停异步函数向下执行,等待Promise返回结果后,再向下继续执行函数
3,await使用异步代码,但是执行时是按照同步形式代码执行顺序

**

async function p1(){
    return 'p2'
}
async function p2(){
    return 'p3'
}
async function p3(){
    return 'p3'
}
function fn(){
     let res1 = await p1()
     let res2 = await p2()
     let res3 = await p3()
}
复制代码

注:上段代码执行的顺序是,先执行 p1() ,得到结构之后赋值给res1,再执行执行 p2() ,得到结构之后赋值给res2,执行 p3() ,得到结构之后赋值给res3,虽然是异步函数,但是按照顺序依次执行

2,Promise.all ( );得到多个promise的结果

**

function  test(x){
    return new Promise((resolve, reject)=>{
        if(x >3){
              resolve()
            }else{
              reject()
        }
   })
}
Promise.all(test(5),test(2)).then((res)=>{
  console.log('成功的回调1')
}).then(()=>{
  console.log('成功的回调2')
}).catch(()=>{
  console.log('失败的回调')
})
复制代码

3,Promise.race( ):返回最先完成的一个任务结果,其他任务依然执行,但是打印不出来

**

function  test(x){
    return new Promise((resolve, reject)=>{
        if(x >3){
              resolve()
            }else{
              reject()
        }
   })
}
Promise.race(test(5),test(2)).then((res)=>{
  console.log('成功的回调1') // 只要 test(5),test(2) 任意一个返回成功,都可以打印出结果
}).then(()=>{
  console.log('成功的回调2')
}).catch(()=>{
  console.log('失败的回调')
})
复制代码

4,用 await 获得多个promise结果

**

async function test(){
    try{
        let n = await Promise.all([text(5),text(2)])
        console.log(n)
    }catch(error){
        console.log(error)
    }
}
test()
复制代码

如果你没有在async函数中写return,那么Promise对象resolve的值就是undefined,如果你写了return,那么return的值就会作为你成功的时候传入的值

promise 的缺点

  • promise一旦新建就会立即执行,无法中途取消
  • 当处于pending状态时,无法得知当前处于哪一个状态,是刚刚开始还是刚刚结束
  • 如果不设置回调函数,promise内部的错误就无法反映到外部
  • promise封装ajax时,由于promise是异步任务,发送请求的步骤会被延后到整个脚本同步代码执行完,并且将响应回调函数延迟到现有队列的最后,如果大量使用会大大降低了请求效率。

补充:

1,常见的内置错误

error:所有错误的父类型
referenceError:引用的变量不存在—引用不存在的变量会报错,如果没有捕获错误,那么下面的代码就不会继续执行
typeError:数据类型不正确的错误—设置一个变量,但是他不存在某些属性,当运行时候,会报此错
rangeError:数据值不在其所允许的范围内
syntaxError:语法错误—不符合常规语法的错误会报错

2,错误处理
1,捕获错误:try ... catch
如果程序出错,还行让程序继续执行,那么使用捕获错误

**

 try {
          let b;
          console.log(b.xxx)
        } catch (error) {
            console.log(error)
        }
  console.log('出错之后,还执行的错误,因为上面捕获了')
复制代码

注:每个error都有两个属性,message与stack
2,抛出错误:throw error

**

 try {
     something()
 } catch (error) {
      console.log(error.message)
 }
function something() {
     if (Date.now() % 2 === 1) {
        console.log('当前时间为奇数,可以执行')
     } else {
        throw new error('当前时间为偶数,不可以执行')
     }
} 
复制代码

3,错误对象
message属性:错误相关信息
stack属性:函数调用栈记录信息

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改