4.Promise常规用法

Promise是JavaScript中处理异步操作的重要工具,它避免了回调地狱,提供了链式调用的方式。Promise构造函数接收一个执行器函数,用于解决或拒绝Promise。通过Promise.all()可以等待所有异步任务完成,而Promise.race()则是哪个任务先完成就执行哪个。在错误处理上,.catch()可以捕获.then()中抛出的异常,并且一旦出现异常,后续的.then()将不再执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Promise

Promise 它表示一个异步操作操作最终成功或者失败。其本质上是一个函数返回的对象,可以在上面绑定回调函数,如此就不需要在一开始将回调函数当作参数传入该异步函数了。

传统的回调函数的使用

// 成功的回调函数
function successCallback(result) {
  console.log('音频文件创建成功: ' + result)
}

// 失败的回调函数
function failureCallback(error) {
  console.log('音频文件创建失败: ' + error)
}

;(function (audioSettings, callback1, callback2) {
  setTimeout(() => {
    console.log(audioSettings)
    if (audioSettings > 5) {
      console.log('successCallback')
      callback1('successCallback')
    } else {
      console.log('failureCallback')
      callback2('failureCallback')
    }
  }, 1000)
})(4, successCallback, failureCallback)

// =>4
// =>failureCallback
// =>音频文件创建失败: failureCallback

promise特点

  • Promise 的构造器接收一个执行函数(executor),我们可以在这个执行函数里手动地 resolve 和 reject 一个 Promise;一个表示fulfilled,一个表示rejected后的回调函数。【两个函数参数】
  • 在本轮 事件循环 运行完成之前,回调函数是不会被调用的。
  • 即使异步操作已经完成(成功或失败),在这之后通过 then() 添加的回调函数也会被调用
  • 通过多次调用 then() 可以添加多个回调函数,它们会按照插入顺序进行执行,即链式调用
// 上例改成promise调用
function createAudioFileAsync(audioSettings) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(audioSettings)
      if (audioSettings > 5) {
        console.log('successCallback')
        resolve('successCallback')
      } else {
        console.log('failureCallback')
        resolve('failureCallback')
      }
    }, 1000)
  })
}

createAudioFileAsync(4).then(successCallback, failureCallback)

Promise组合工具

  • Promise.resolve()/Promise.reject()

    可以通过手动返回成功或者失败的回调结果:

Promise.resolve()
手动设置异步成功执行的结果,直接Promise.resolve返回值

const promise1 = Promise.resolve(123);
promise1.then((value) => {
  console.log(value);
  // expected output: 123
});

Promise.reject()
手动设置异步失败执行的结果,直接Promise.reject返回值

function resolved(result) {
  console.log('Resolved');
}
function rejected(result) {
  console.error(result);
}
Promise.reject(new Error('fail')).then(resolved, rejected);
// expected output: Error: fail
  • Promise.all()
Promise.all([func1(), func2(), func3()])
.then(([result1, result2, result3]) => { 
/* use result1, result2 and result3,全部返回,一起用 */ });

该组合函数表示,等待异步函数func1,func2,func3三个函数都返回结果之后再,执行.then()函数;
适用于需要多个接口返回接口后,才执行某个触发的场景,如多个接口返回数据,然后取消loading。

const func1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1)
  }, 1000)
})

const func2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(2)
  }, 2000)
})

const func3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(3)
  }, 3000)
})
console.time('time')   // console.time(XXX)和console.timeEnd(XXX)中参数需保持一致
const promiseAll = Promise.all([func1, func2, func3])
  .then((res) => {
    console.timeEnd('time') // 耗时三秒,说明以最长时间之后才执行.then()回调函数
    console.log(res)
  })
  .catch((err) => {
    console.log(err)
  })
// =>time: 3002.290ms   耗时三秒
// =>[ 1, 2, 3 ]
  • promise.race()
Promise.all([func1(), func2(), func3()])
.then(([result1, result2, result3]) => { 
/* result1, result2 and result3,谁先返回,就用谁 */
 });

Promise.race()表示多个异步函数中,哪个函数先返回结果,就直接以该结果,进行.then()的回调函数的执行;

const func1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1)
  }, 1000)
})

const func2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(2)
  }, 2000)
})

const func3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(3)
  }, 3000)
})
console.time('time')
const promiseAll = Promise.race([func1, func2, func3])
  .then((res) => {
    console.timeEnd('time')
    console.log(res)
  })
  .catch((err) => {
    console.log(err)
  })
// 时间不一定严格为1秒钟,因为本身setTimeout,或者setInterVal()等宏任务就需要等待执行时间
// =>time: 1006.057ms    
// =>1

.catch()

注意:

  1. 只要.then()抛出异常,就立即停止后续代码的执行,直接被.catch()捕获异常;
new Promise((resolve, reject) => {
    console.log('初始化');
    resolve();
})
.then(() => {
    throw new Error('有哪里不对了');
    console.log('第一个回调then');
})
.catch(() => {
    console.log('第二个回调catch');
})
.then(() => {
    console.log('执行第三个回调then,无论前面发生了什么');
});

 // =>初始化
 // =>第二个回调catch
 // =>执行第三个回调then,无论前面发生了什么

  1. 错误传递,如果回调函数中有异常抛出,会顺延寻找后续的第一个.catch(),执行抛错后的操作,在此之前的.then()回调都不会执行,如果没有.catch(),则抛错后不会执行后续的回调,浏览器控制台会捕获异常;
new Promise((resolve, reject) => {
    console.log('初始化');
    resolve();
})
.then(() => {
    throw new Error('有哪里不对了');Ï
    console.log('异常抛出,此行不执行');
})
.then(() => {
    console.log('未找到异常捕获回调,不执行');
}).then(() => {
    console.log('未找到异常捕获回调,不执行');
}).catch(() => {
    console.log('找到异常捕获回调,执行此行');
}).catch(() => {
    console.log('异常前面已捕获,不执行');
})

 // =>初始化
 // =>找到异常捕获回调,执行此行
 // =>Promise {<fulfilled>: undefined}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值