【鸿蒙】---鸿蒙Next小课堂之Promise

前言

Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。简而言之:Promise 用来管理异步,方便编码。

这时候该有人要问了,怎么区分异步和同步呢?

同步代码:逐行执行,需原地等待结果后,才继续向下执行。
异步代码:调用后耗时,不阻塞代码继续执行,将来完成后,触发回调函数传递结果。
划重点:异步代码的结果,通过 回调函数 获取。

Promise 状态

Promis有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。

  1. 待定(pending): 初始状态,既没有被兑现,也没有被拒绝
  2. 已完成(fullfilled): 意味着操作成功完成
  3. 已拒绝(rejected): 意味着操作失败

在这里插入图片描述

注意:状态的改变不可逆
调用 resolve 之后再调用 reject,状态还是 已兑现,反之亦然

Promise 什么用法

Promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected状态。所以使用Promise 来管理异步任务主要有三个步骤,分别对应:

  1. 内部执行异步代码
  // 实例化 Promise 对象
  const p = new Promise<string>(() => {
    // 执行任意代码,主要是异步
    setTimeout(() => {
      // 比如:获取随机数
      const randomNum = Math.floor(Math.random() * 100)
      console.log('随机数是:', randomNum)
    })
  })
}
  1. 传递成功结果
const p = new Promise<string>((resolve) => {
    // 执行任意代码,主要是异步
    setTimeout(() => {
      // 比如:获取随机数
      const randomNum = Math.floor(Math.random() * 100)
      resolve(randomNum.toString())
    })
  })

  p.then(res => {
    console.log('res:', res)
  })
  1. 传递失败结果
  const p = new Promise<string>((resolve,reject) => {
      // 执行任意代码,主要是异步
      setTimeout(() => {
        // 比如:获取随机数
        const randomNum = Math.floor(Math.random() * 100)
        // resolve(randomNum.toString())
        reject(randomNum.toString())
      })
    })

    p.then(res => {
      console.log('res:', res)
    },(err:string)=>{
      console.log('err:',err)
    })

做个总结就是

    const p = new Promise<string>((resolve, reject) => {
      // 执行任意代码,主要是异步
      // 成功 resolve(成功结果) then 执行
      // 失败 reject(失败结果) then第二个回调函数或 catch 执行
    })

    p.then(res => {}, (err: string) => {})
    
    p.then(res=>{}).catch((err:string)=>{})

Promise 为什么用

如果回调函数一直【嵌套】下去,代码的可读性会非常糟糕。
一般在多个异步操作【彼此依赖】的时候会出现回调函数嵌套的情况,(c 依赖 b,b 依赖 a),就会产生以下的情况。

promise对象a.then(res1=>{
  promise对象b.then(res2=>{
    promise对象c.then(res3=>{
      promise对象d.then(res4=>{
        //.... 可以一直写下去
      })
    })
  })
})

上述写法就叫做回调函数地狱

Promise 怎么用

这种写法较为繁琐,所以我们可以使用 Promise 的链式编程来解决这个问题。

这里是引用

这样写是 Promise 对象的特性:
Promise 的 then 方法会返回一个新Promise 对象
then 方法的返回值会影响这个 新Promise对象的结果

简单表述出来就是

promise对象
.then(() => {
// 略
}).then(()=>{
// 略
}).then(()=>{
// 略
})

在代码里的具体实现为

function randomNum(delay: number): Promise<string> {
  return new Promise<string>((resolve, reject) => {
    const num = Math.floor(Math.random() * 100)
    resolve(num.toString())
  })
}

randomNum(1000)
  .then(res => {
    console.log('随机数1:', res)
    return randomNum(2000)
  })
  .then(res => {
    console.log('随机数2:', res)
    return randomNum(3000)
  })
  .then(res => {
    console.log('随机数3:', res)
    return randomNum(3000)
  })

Promise 的静态方法

日常开发中除了使用 Promise 对象以外,还可以通过 Promise 提供的静态方法来管理多个异步。

Promise.resolve
返回一个成功原因的 Promise 对象

Promise.resolve('hello resolve')
  .then(res => {
    AlertDialog.show({ message: res })
  })

Promise.reject
返回一个拒绝原因的 Promise 对象

Promise.reject('hello reject')
  .catch((err: string) => {
    AlertDialog.show({ message: err })
  })

Promisse.race
传入 Promise 数组,第一个成功或者失败

const p1 = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    resolve('2')
  }, 2000)
})
const p2 = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    reject('1')
  }, 1000)
})
Promise.race([p1, p2, 'Harmony']).then((res) => {
  console.log('res:', res)
}, (err:string) => {
  console.log('err:', err)
})

Promise.all
多个 Promise,全部成功,或者第一个失败

const p1 = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    resolve('1')
  }, 2000)
})
const p2 = new Promise<string>((resolve, reject) => {
  setTimeout(() => {
    reject('2')
  }, 1000)
})
Promise.all([p1, p2, 'Harmony'])
  .then((res) => {
    console.log('res:', res)
  }, (err: string) => {
    console.log('err:', err)
  })
  • 37
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值