解决异步的方法promise

90 阅读2分钟

异步

console.log(1);
setTimeout(() => {
  a = 2
  console.log(2)
}, 1000)
console.log(3)

当程序中,遇到需要耗时的代码时,会将其挂起,等待后序代码运行结束后,再开始执行

js异步产生的原因

  1. js是一个单线程语言,一次只能干一件事(多线程执行执行开销性能高,开发难度大)
  2. js遇到需要耗时执行的代码就将其先挂起,等到后序不耗时的的代码执行完后来执行

解决异步

回调

回调函数是最早出现的异步编程方式。它的基本思想是将一个函数作为参数传递给另一个函数,这个被传递的函数会在某个异步操作完成时调用。

function fetchData(callback) {
    setTimeout(() => {
        const data = "some data";
        callback(data);
    }, 1000);
}
 
fetchData((data) => {
    console.log(data); // 输出 "some data"
});

回调的缺陷: 回调地狱(Callback Hell)是指当你有多个异步操作需要依次执行,并且每个操作都依赖于前一个操作的结果时,代码会嵌套成多层回调函数,导致结构复杂、难以理解和维护。

function a(cb, cb2, cb3) {
  setTimeout(() => {
    console.log('a 执行完毕')
    cb(cb2, cb3)
  }, 1000)
}

function b(cb, cb3) {
  setTimeout(() => {
    console.log('b 执行完毕')
    cb(cb3)
  }, 1500)
}

function c(cb) {
  setTimeout(() => {
    console.log('c 执行完毕')
    cb()
  }, 500)
}

function d() {
  console.log('d 执行完毕');
}

a(b, c, d)

代码被层层调用,报错难以找到问题

promise

Promise 是为了解决回调地狱(Callback Hell)问题而引入的。Promise 对象代表一个最终可能完成(并返回结果)或失败(并返回原因)的异步操作。

基本用法

创建一个 Promise

你可以使用 new Promise 构造函数来创建一个 Promise 对象。这个构造函数接受一个执行器函数(executor function),这个函数有两个参数:resolve 和 reject,它们都是函数。

let promise = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    let success = true; // 假设这是某种异步操作的结果
    if (success) {
      resolve('操作成功');
    } else {
      reject('操作失败');
    }
  }, 1000);
});
使用 Promise

Promise 对象有两个主要的方法:then 和 catch,用于处理成功和失败的情况。

promise
  .then(result => {
    console.log(result); // 输出: 操作成功
  })
  .catch(error => {
    console.error(error); // 如果失败,则输出: 操作失败
  });

Promise 的状态

一个 Promise 对象有以下三种状态:

  1. Pending(等待中) :初始状态,既不是成功也不是失败。
  2. Fulfilled(已成功) :意味着操作成功完成。
  3. Rejected(已失败) :意味着操作失败。

链式调用

then 方法返回一个新的 Promise,这使得可以进行链式调用。每个 then 方法可以接收两个函数作为参数,第一个函数是处理成功的情况,第二个函数(可选)是处理失败的情况。

doSomething()
  .then(result => doSomethingElse(result))
  .then(newResult => doThirdThing(newResult))
  .then(finalResult => {
    console.log(`最终结果: ${finalResult}`);
  })
  .catch(failureCallback);