Promise

Promise

状态(States): Promise 有三种状态:pending(进行中)、fulfilled(已完成)、rejected(已拒绝)。在创建 Promise 对象时,它的状态是 pending,然后可能会变为 fulfilled 或 rejected,一旦状态确定,就不会再改变。

值和原因(Value and Reason): 当 Promise 转为 fulfilled 状态时,会返回一个结果值;而当转为 rejected 状态时,会返回一个拒绝原因。

then() 方法: Promise 提供了 then() 方法,用于处理异步操作的结果。它接收两个参数:第一个参数是处理成功状态的回调函数,第二个参数是处理拒绝状态的回调函数。

catch() 方法: 与 then() 方法不同,catch() 方法只用于处理 Promise 的拒绝状态。它是 then(null, rejection) 的别名,用于捕获 Promise 中的异常。

链式调用: Promise 的 then() 方法和 catch() 方法可以链式调用,以便更清晰地处理多个异步操作。

Promise.all() 和 Promise.race(): Promise.all() 方法接收一个 Promise 数组作为参数,当数组中的所有 Promise 都变为 fulfilled 状态时,它才会变为 fulfilled 状态,并返回所有 Promise 结果的数组;Promise.race() 方法也接收一个 Promise 数组作为参数,但只要数组中的任意一个 Promise 变为 fulfilled 或 rejected 状态,它就会相应地变为相应的状态,并返回第一个完成的 Promise 结果或原因。

const PENDING = 'pending'
const FULFILLED = 'fullfilled'
const REJECTED = 'rejected'

function myPromise(fn) {
  this.state = PENDING
  this.value = null
  const that = this
  that.resolvedCallbacks = []
  that.rejectedCallbacks = []

  function resolve(val) {
    if (that.state == PENDING) {
      that.state = FULFILLED
      that.value = val
      that.resolvedCallbacks.map((cb)=>{
        cb(that.value)
      })
    }
  }
  function reject(val) {
    if (that.state == PENDING) {
      that.state = REJECTED
      that.value = val
      that.rejectedCallbacks.map((cb)=>{
        cb(that.value)
      })
    }
  }

  try {
    fn(resolve, reject)
  } catch (error) {
    reject(error)
  }

}

myPromise.prototype.then = function (onFullfilled, onRejected) {
  const that = this
  onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : v => v
  onRejected= typeof onRejected === 'function' ? onRejected : r => { throw r }

  if(that.state===PENDING){
    that.resolvedCallbacks.push(onFullfilled)
    that.resolvedCallbacks.push(onRejected)
  }
  if (that.state === FULFILLED) {
    onFullfilled(that.value)
  }
  if (that.state === REJECTED) {
    onRejected(that.value)
  }
} 

//验证   ok ok
let p = new myPromise((resolve, reject) => {
  // reject('fail')
  resolve('ok')
})

p.then((res) => {
  console.log(res,'ok');
}, (err) => {
  console.log(err,'fail');
})

Promise案例

// 一个模拟的异步函数,用于获取用户信息
function getUserInfo() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = true; // 模拟成功或失败的情况,这里设为 true 表示成功
      if (success) {
        const userInfo = {
          id: 1,
          name: 'John Doe',
          email: 'john@example.com'
        };
        resolve(userInfo); // 成功时调用 resolve,并传递用户信息
      } else {
        reject('获取用户信息失败'); // 失败时调用 reject,并传递错误信息
      }
    }, 1000); // 模拟异步延迟
  });
}

// 使用 Promise 的 then() 和 catch() 方法处理异步操作
getUserInfo()
  .then((userInfo) => {
    console.log('成功获取用户信息:', userInfo);
  })
  .catch((error) => {
    console.error('获取用户信息失败:', error);
  });

在上述示例中,getUserInfo() 是一个模拟的异步函数,它返回一个 Promise 对象。在这个函数中,我们使用 setTimeout() 来模拟一个异步操作,然后根据模拟的结果来调用 resolve() 或 reject() 来决定 Promise 的状态。在成功时,我们使用 resolve() 来传递用户信息,而在失败时,我们使用 reject() 来传递错误信息。

然后,我们通过 then() 方法来处理异步操作的成功状态,它接收一个回调函数作为参数,该回调函数会在 Promise 的状态变为 fulfilled 时被调用,并接收 resolve() 传递的用户信息作为参数。而通过 catch() 方法来处理异步操作的拒绝状态,它接收一个回调函数作为参数,该回调函数会在 Promise 的状态变为 rejected 时被调用,并接收 reject() 传递的错误信息作为参数。

当运行这个示例时,你会看到在模拟的异步操作完成后,根据成功或失败的情况,分别输出不同的结果。

async/await

async/await 是基于 Promise 的一种语法糖,它是一种更直观和简洁的方式来处理异步操作。async/await 让异步代码看起来更像同步代码,使得异步操作的处理更加清晰和易读。

Promise:

使用 new Promise() 构造函数来创建一个 Promise 对象。
使用 .then() 方法来处理 Promise 的成功状态。
使用 .catch() 方法来处理 Promise 的拒绝状态。
可以使用 .finally() 方法来添加在 Promise 结束后总是会执行的代码。
可以通过 Promise 链来串行多个异步操作,使得代码更加简洁。
可以使用 Promise.all() 方法来并行处理多个 Promise,当所有 Promise 都完成时才会继续执行后续代码。
可以使用 Promise.race() 方法来并行处理多个 Promise,当任意一个 Promise 完成时就会继续执行后续代码。

async/await:

使用 async 关键字声明一个函数为异步函数。
在异步函数中使用 await 关键字来等待一个 Promise 完成,并将结果赋给变量。await 只能在异步函数内部使用。
异步函数的返回值是一个 Promise,它的结果由异步函数的返回值决定。
使用 try/catch 块来处理异步操作的异常,并使用 throw 来抛出异常。
可以使用 async/await 语法来替代 Promise.then() 和 Promise.catch(),使得代码看起来更加简洁。

比较:

async/await 相对于 Promise 来说,代码更加简洁易读,特别是处理多个异步操作时更方便。
async/await 让异步代码看起来更像同步代码,更符合直觉,减少了回调地狱。
async/await 依赖于 Promise,它们并不是相互独立的,实际上,使用 async/await 语法的异步函数内部依然是基于 Promise 来实现的。
async/await 可能会让异常处理更加清晰,因为可以使用 try/catch 来捕获异步操作中的异常。
对于较旧的浏览器或环境,可能不支持 async/await,因此在这些情况下,仍然需要使用 Promise。

综上所述,async/await 是一种更高级、更易用的异步处理方式,它建立在 Promise 的基础上,并通过更简洁的语法来优化异步代码的编写和可读性。
示例:

// 模拟一个返回 Promise 的异步函数
function getUserInfo() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = true; // 模拟成功或失败的情况,这里设为 true 表示成功
      if (success) {
        const userInfo = {
          id: 1,
          name: 'John Doe',
          email: 'john@example.com'
        };
        resolve(userInfo); // 成功时调用 resolve,并传递用户信息
      } else {
        reject('获取用户信息失败'); // 失败时调用 reject,并传递错误信息
      }
    }, 1000); // 模拟异步延迟
  });
}

// 使用 async/await 处理异步操作
async function fetchUserInfo() {
  try {
    const userInfo = await getUserInfo(); // 等待异步操作完成,并将结果赋值给变量
    console.log('成功获取用户信息:', userInfo);
  } catch (error) {
    console.error('获取用户信息失败:', error);
  }
}

fetchUserInfo(); // 调用异步函数

在上述代码中,getUserInfo() 是一个模拟的异步函数,它返回一个 Promise 对象。我们通过 async 关键字将 fetchUserInfo() 声明为异步函数,并在其中使用 await 关键字来等待 getUserInfo() 异步操作完成,并将结果赋值给 userInfo 变量。

在 fetchUserInfo() 函数中,我们使用 try/catch 块来处理异步操作的成功和失败情况。如果异步操作成功,await 返回的结果会被赋值给 userInfo 变量,并且会在 try 块内输出成功获取的用户信息。如果异步操作失败,会抛出一个错误,并在 catch 块内输出获取用户信息失败的错误信息。

通过使用 async/await,异步代码的编写看起来更像同步代码,并且异常处理更加直观和简洁。

为什么async之后需要await

在 JavaScript 中,async 关键字用于声明一个函数是异步函数,即函数内部可能包含异步操作。异步函数会返回一个 Promise 对象,这个 Promise 对象的状态和值由异步函数的执行结果决定。

当我们在异步函数内部执行异步操作时,可能需要等待这些异步操作的完成,然后再继续执行后续的代码。在这种情况下,我们使用 await 关键字。

await 关键字用于暂停异步函数的执行,等待一个 Promise 对象的状态变为 fulfilled(成功)或 rejected(失败)。如果等待的 Promise 对象状态为 fulfilled,await 表达式会返回 Promise 的结果值;如果等待的 Promise 对象状态为 rejected,await 表达式会抛出一个异常,可以通过 try/catch 来处理。

在使用 await 关键字时,我们需要将其放置在一个异步函数中,因为 await 只能在异步函数内部使用。异步函数通过返回一个 Promise 对象来表明其执行状态。

这里有一个简单的示例来展示为什么 async 后面需要 await:

// 异步函数,返回一个 Promise 对象
async function fetchData() {
  return Promise.resolve('这是异步操作的结果');
}

// 同步函数,不需要使用 await
function syncFunction() {
  return '这是同步操作的结果';
}

async function main() {
  const asyncResult = await fetchData(); // 等待异步操作完成并获取结果
  console.log('异步操作结果:', asyncResult);

  const syncResult = syncFunction(); // 同步操作直接执行,无需等待
  console.log('同步操作结果:', syncResult);
}

main();

在上面的示例中,fetchData() 是一个异步函数,返回一个 Promise 对象。在 main() 函数中,我们使用 await 来等待 fetchData() 的异步操作完成,并获取异步操作的结果。而 syncFunction() 是一个同步函数,不需要使用 await,它会直接执行并返回结果。

因此,async 关键字用于声明一个函数是异步函数,而 await 关键字用于等待异步操作的结果,以便在异步操作完成后继续执行后续的代码。这样我们可以编写更加直观和简洁的异步代码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值