阿里云主机折上折
  • 微信号
Current Site:Index > The basic concept of Promise and its three states.

The basic concept of Promise and its three states.

Author:Chuan Chen 阅读数:44555人阅读 分类: JavaScript

ECMAScript 6 introduced Promises as a solution for asynchronous programming, addressing the issue of deeply nested callback functions. A Promise object represents the eventual completion or failure of an asynchronous operation and allows handling the result of the operation in a chained manner.

Basic Concepts of Promises

A Promise is an object representing the eventual state (fulfillment or rejection) and result value of an asynchronous operation. It has three states: pending (in progress), fulfilled (successfully completed), and rejected (failed). Once a Promise transitions from pending to either fulfilled or rejected, its state cannot change again.

The Promise constructor takes a function as an argument, known as the executor. The executor function has two parameters: resolve and reject, which are callback functions for success and failure, respectively. For example:

const promise = new Promise((resolve, reject) => {
  // Asynchronous operation
  setTimeout(() => {
    const randomNumber = Math.random();
    if (randomNumber > 0.5) {
      resolve(randomNumber); // Call resolve on success
    } else {
      reject(new Error('Number is too small')); // Call reject on failure
    }
  }, 1000);
});

The Three States of a Promise

1. Pending (In Progress)

The initial state of a Promise is pending, indicating that the asynchronous operation has not yet completed. At this stage, the Promise has neither been resolved nor rejected. For example:

const promise = new Promise((resolve, reject) => {
  // Asynchronous operation not yet completed
  console.log('Promise is pending');
});

console.log(promise); // Output: Promise { <pending> }

2. Fulfilled (Successfully Completed)

When a Promise transitions from pending to fulfilled, it means the asynchronous operation has succeeded. At this point, the resolve function is called, passing the result value. For example:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Operation succeeded');
  }, 1000);
});

promise.then((result) => {
  console.log(result); // Output: Operation succeeded
});

3. Rejected (Failed)

When a Promise transitions from pending to rejected, it means the asynchronous operation has failed. At this point, the reject function is called, passing the error information. For example:

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('Operation failed'));
  }, 1000);
});

promise.catch((error) => {
  console.error(error.message); // Output: Operation failed
});

State Transition of Promises

Once a Promise transitions from pending to either fulfilled or rejected, the state cannot be reversed. For example:

const promise = new Promise((resolve, reject) => {
  resolve('First resolve'); // State changes to fulfilled
  reject(new Error('This will be ignored')); // Ineffective, state won't change
});

promise.then((result) => {
  console.log(result); // Output: First resolve
});

Chaining Promises

Promises support chaining through the then and catch methods, allowing you to handle the results or errors of asynchronous operations. For example:

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched');
    }, 1000);
  });
};

fetchData()
  .then((data) => {
    console.log(data); // Output: Data fetched
    return 'Processed data';
  })
  .then((processedData) => {
    console.log(processedData); // Output: Processed data
  })
  .catch((error) => {
    console.error(error);
  });

Static Methods of Promises

Promises provide several static methods for handling multiple Promises or creating Promises with specific states.

Promise.resolve

Promise.resolve returns a Promise that is already in the fulfilled state. For example:

const resolvedPromise = Promise.resolve('Resolved value');

resolvedPromise.then((value) => {
  console.log(value); // Output: Resolved value
});

Promise.reject

Promise.reject returns a Promise that is already in the rejected state. For example:

const rejectedPromise = Promise.reject(new Error('Rejected'));

rejectedPromise.catch((error) => {
  console.error(error.message); // Output: Rejected
});

Promise.all

Promise.all takes an array of Promises and returns a new Promise that resolves with an array of results when all Promises succeed, or rejects with the error of the first failed Promise. For example:

const promise1 = Promise.resolve('First');
const promise2 = Promise.resolve('Second');
const promise3 = Promise.reject(new Error('Third failed'));

Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results); // Will not execute
  })
  .catch((error) => {
    console.error(error.message); // Output: Third failed
  });

Promise.race

Promise.race takes an array of Promises and returns a new Promise that resolves or rejects with the result of the first Promise to complete (regardless of success or failure). For example:

const promise1 = new Promise((resolve) => {
  setTimeout(() => resolve('First'), 500);
});
const promise2 = new Promise((resolve) => {
  setTimeout(() => resolve('Second'), 1000);
});

Promise.race([promise1, promise2])
  .then((result) => {
    console.log(result); // Output: First
  });

Error Handling in Promises

Errors in Promises can be caught using the catch method or the second parameter of the then method. For example:

const promise = new Promise((resolve, reject) => {
  reject(new Error('Something went wrong'));
});

// Method 1: Using catch
promise
  .then((result) => {
    console.log(result);
  })
  .catch((error) => {
    console.error(error.message); // Output: Something went wrong
  });

// Method 2: Using the second parameter of then
promise.then(
  (result) => {
    console.log(result);
  },
  (error) => {
    console.error(error.message); // Output: Something went wrong
  }
);

Practical Applications of Promises

Promises are commonly used in real-world development for handling asynchronous operations, such as network requests or file reading. Here’s an example simulating a network request:

const fetchUserData = (userId) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (userId === 1) {
        resolve({ id: 1, name: 'Alice' });
      } else {
        reject(new Error('User not found'));
      }
    }, 1000);
  });
};

fetchUserData(1)
  .then((user) => {
    console.log(user); // Output: { id: 1, name: 'Alice' }
  })
  .catch((error) => {
    console.error(error.message);
  });

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.