Skip to content
本页目录

JavaScript Promise

Promise是一种异步编程的解决方案,它可以避免回调地狱,使代码更加简洁易读。Promise对象代表一个异步操作的最终完成或失败,并返回一个值。

在 JavaScript 中,Promise有三种状态:pending(进行中)fulfilled(已成功)rejected(已失败)。当Promise对象的状态从pending变为fulfilledrejected时,会调用相应的回调函数。

JavaScript Promise 是一种用于处理异步操作的对象,它表示一个异步操作的最终完成(或失败)及其结果的值。

Promise 通过链式调用的方式,使得异步操作的处理更加优雅和可读。它可以避免回调地狱(callback hell)的问题,使异步代码更易于理解和维护。

以下是 Promise 的基本概念和用法:

创建 Promise

Promise 可以通过 new Promise() 构造函数来创建。它接收一个带有两个参数的回调函数,回调函数包含两个参数:resolvereject

javascript
const promise = new Promise((resolve, reject) => {
  // 异步操作
  // 在操作成功时调用 resolve(value)
  // 在操作失败时调用 reject(error)
})

在回调函数中,可以执行异步操作,例如发送网络请求、读取文件等。当异步操作成功时,调用 resolve(value),并将成功的结果 value 传递给它;当异步操作失败时,调用 reject(error),并将错误信息 error 传递给它。

处理 Promise 结果

通过调用 Promise 实例的 .then() 方法可以处理异步操作成功的结果,通过调用 .catch() 方法可以处理异步操作失败的结果。

javascript
promise
  .then((value) => {
    // 处理成功的结果
  })
  .catch((error) => {
    // 处理失败的结果
  })

.then() 方法中传递的函数会在异步操作成功时被调用,并接收到成功的结果 value。在 .catch() 方法中传递的函数会在异步操作失败时被调用,并接收到错误信息 error

Promise 链式调用

Promise 的一个重要特性是可以通过链式调用来串联多个异步操作。通过在 .then() 方法中返回新的 Promise 实例,可以将多个异步操作连接起来。

javascript
promise
  .then((value) => {
    // 处理第一个操作成功的结果
    return anotherPromise
  })
  .then((value) => {
    // 处理第二个操作成功的结果
    return yetAnotherPromise
  })
  .catch((error) => {
    // 处理任意一个操作失败的结果
  })

在上述示例中,第一个 .then() 方法返回了一个新的 Promise 实例 anotherPromise。这样,可以在第二个 .then() 方法中继续处理 anotherPromise 成功的结果,并返回另一个 Promise 实例 yetAnotherPromise。如果任意一个操作失败,将调用最后的 .catch() 方法。

Promise.all()

Promise.all() 方法接收一个 Promise 实例数组,返回一个新的 Promise 实例。该新实例在数组中的所有 Promise 实例都成功完成时才会成功,并将所有 Promise 实例的结果作为一个数组传递给 .then() 方法。

javascript
const promises = [promise1, promise2, promise3]
Promise.all(promises)
  .then((results) => {
    // 处理所有 Promise 实例成功的结果
  })
  .catch((error) => {
    // 处理任意一个 Promise 实例失败的结果
  })

在上述示例中,Promise.all() 接收一个 Promise 实例数组 promises,并返回一个新的 Promise 实例。当 promises 中的所有 Promise 实例都成功完成时,新的 Promise 实例的 .then() 方法会被调用,传递一个包含所有 Promise 实例结果的数组 results。如果任意一个 Promise 实例失败,将调用新 Promise 实例的 .catch() 方法。

TIP

Promise 还有许多其他方法和特性,例如 Promise.race()Promise.resolve()Promise.reject() 等,它们提供了更多的灵活性和功能。通过使用 Promise,可以更好地处理异步操作,避免回调地狱,并使代码更清晰和可维护。

使用 Promise 封装一个 Ajax

下面是一个使用 Promise 封装的基本 Ajax 请求的示例:

javascript
function ajax(url, method, data) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open(method, url)
    xhr.setRequestHeader('Content-Type', 'application/json')
    xhr.onload = function () {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(xhr.responseText)
      } else {
        reject(new Error(xhr.statusText))
      }
    }
    xhr.onerror = function () {
      reject(new Error('Network Error'))
    }
    xhr.send(JSON.stringify(data))
  })
}

// 示例用法
const requestData = {
  username: 'example',
  password: 'password'
}

ajax('https://api.example.com/login', 'POST', requestData)
  .then((response) => {
    console.log('Response:', response)
  })
  .catch((error) => {
    console.error('Error:', error)
  })

在上述示例中,ajax 函数封装了一个基本的 Ajax 请求。它接收三个参数:请求的 URL、请求的方法(例如 GET、POST)和请求的数据(可选)。函数内部创建了一个 XMLHttpRequest 对象,并使用传递的参数设置请求的相关属性。然后,使用 xhr.send() 方法发送请求。

当请求成功完成时,xhr.onload 事件被触发,函数判断响应的状态码,如果在 200 到 299 的范围内,则调用 resolve(xhr.responseText) 将响应文本作为成功的结果传递给 Promise。否则,调用 reject(new Error(xhr.statusText)) 将状态文本作为错误信息传递给 Promise。

当请求发生错误时,xhr.onerror 事件被触发,函数调用 reject(new Error('Network Error')) 将网络错误信息传递给 Promise。

使用封装的 ajax 函数,可以通过 Promise 的 .then() 方法处理请求成功的响应,通过 .catch() 方法处理请求失败的错误。

注意,上述示例中假设请求的数据为 JSON 格式,并设置请求头的 Content-Type 为 application/json。根据具体的需求,可以调整请求的数据和请求头。

通过封装 Ajax 请求为 Promise,可以更优雅地处理异步请求,并使用 Promise 的链式调用、错误处理和其他特性来组织和处理请求的结果。

lemon's personal blog.