阿里云主机折上折
  • 微信号
Current Site:Index > The static methods of Promise

The static methods of Promise

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

ECMAScript 6 introduced Promise as the core solution for asynchronous programming, with its static methods providing more flexible ways to handle asynchronous operations. These methods include Promise.resolve, Promise.reject, Promise.all, Promise.race, Promise.allSettled, and Promise.any, each designed for different scenarios.

Promise.resolve

Promise.resolve creates an immediately resolved Promise object with the passed-in value as its resolution. If the argument is already a Promise, it returns that Promise directly.

const resolvedPromise = Promise.resolve('Immediately resolved value');
resolvedPromise.then(value => {
  console.log(value); // Output: 'Immediately resolved value'
});

const existingPromise = new Promise(resolve => setTimeout(() => resolve('Original Promise'), 1000));
const wrappedPromise = Promise.resolve(existingPromise);
wrappedPromise.then(value => {
  console.log(value); // Output after 1 second: 'Original Promise'
});

Promise.resolve is particularly useful when converting non-Promise values to Promises. For example, when a function might return either a synchronous value or a Promise:

function fetchData(maybeAsync) {
  return Promise.resolve(maybeAsync).then(data => {
    console.log('Processing data:', data);
  });
}

fetchData(42); // Synchronous value
fetchData(Promise.resolve('Asynchronous value')); // Promise

Promise.reject

Promise.reject creates an immediately rejected Promise object with the passed-in reason for rejection.

const rejectedPromise = Promise.reject(new Error('Operation failed'));
rejectedPromise.catch(error => {
  console.error(error.message); // Output: 'Operation failed'
});

When you need to explicitly indicate a failed asynchronous operation, you can use Promise.reject directly:

function validateInput(input) {
  if (!input) {
    return Promise.reject(new Error('Input cannot be empty'));
  }
  return processInput(input);
}

Promise.all

Promise.all takes an iterable of Promises and returns a single Promise that resolves to an array of all results when all Promises are successfully resolved. If any Promise is rejected, it immediately rejects.

const promise1 = Promise.resolve(1);
const promise2 = new Promise(resolve => setTimeout(() => resolve(2), 1000));
const promise3 = 3; // Non-Promise values are converted via Promise.resolve

Promise.all([promise1, promise2, promise3])
  .then(values => {
    console.log(values); // Output after ~1 second: [1, 2, 3]
  })
  .catch(error => {
    console.error('One of them failed:', error);
  });

A typical use case is parallel execution of multiple independent asynchronous operations:

function fetchUserData() {
  return Promise.all([
    fetch('/api/user'),
    fetch('/api/user/settings'),
    fetch('/api/user/friends')
  ]).then(([user, settings, friends]) => {
    return { user, settings, friends };
  });
}

If one of the requests fails, the entire Promise.all immediately terminates:

Promise.all([
  Promise.resolve('Success 1'),
  Promise.reject(new Error('Failure')),
  Promise.resolve('Success 2')
]).catch(error => {
  console.error(error.message); // Output: 'Failure'
});

Promise.race

Promise.race takes an iterable of Promises and returns the first Promise that settles (either resolves or rejects).

const fastPromise = new Promise(resolve => setTimeout(() => resolve('Fast'), 100));
const slowPromise = new Promise(resolve => setTimeout(() => resolve('Slow'), 500));

Promise.race([fastPromise, slowPromise])
  .then(value => {
    console.log(value); // Output after ~100ms: 'Fast'
  });

In practice, it can be used for timeout control:

function withTimeout(promise, timeout) {
  return Promise.race([
    promise,
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error('Operation timed out')), timeout)
    )
  ]);
}

const apiCall = fetch('/api/data');
withTimeout(apiCall, 3000)
  .then(data => console.log('Successfully fetched data'))
  .catch(error => console.error(error.message)); // Throws timeout error if not completed within 3 seconds

Promise.allSettled

Promise.allSettled waits for all Promises to settle (either resolve or reject) and returns an array of objects describing each Promise's outcome.

const promises = [
  Promise.resolve('Success'),
  Promise.reject(new Error('Failure')),
  new Promise(resolve => setTimeout(() => resolve('Delayed success'), 1000))
];

Promise.allSettled(promises)
  .then(results => {
    results.forEach(result => {
      if (result.status === 'fulfilled') {
        console.log('Success:', result.value);
      } else {
        console.error('Failure:', result.reason.message);
      }
    });
  });
/* Output:
   Success: Success
   Failure: Failure
   Success: Delayed success (after ~1 second)
*/

This is particularly useful when you need to ensure all operations complete before processing the results:

async function logOperationResults(operations) {
  const results = await Promise.allSettled(operations);
  const report = results.map(result => 
    result.status === 'fulfilled' 
      ? { status: 'success', data: result.value }
      : { status: 'error', error: result.reason }
  );
  saveToDatabase(report);
}

Promise.any

Promise.any takes an iterable of Promises and returns the first one that successfully resolves. If all Promises are rejected, it throws an AggregateError.

const server1 = new Promise((_, reject) => 
  setTimeout(() => reject(new Error('Server 1 down')), 200)
);
const server2 = new Promise(resolve => 
  setTimeout(() => resolve('Server 2 responded'), 100)
);
const server3 = new Promise((_, reject) => 
  setTimeout(() => reject(new Error('Server 3 timeout')), 300)
);

Promise.any([server1, server2, server3])
  .then(firstResponse => {
    console.log('Using response:', firstResponse); // Output after ~100ms: 'Server 2 responded'
  })
  .catch(error => {
    console.error('All servers failed:', error.errors);
  });

When multiple fallback options are available, Promise.any can implement a fastest-first selection:

function fetchFromFastestMirror(mirrors) {
  return Promise.any(mirrors.map(url => 
    fetch(url).then(response => {
      if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
      return response.json();
    })
  )).then(data => {
    console.log('Fetched data from fastest mirror:', data);
    return data;
  });
}

If all Promises are rejected, it collects all errors:

Promise.any([
  Promise.reject(new Error('Error 1')),
  Promise.reject(new Error('Error 2'))
]).catch(error => {
  console.error('All failed:');
  error.errors.forEach(e => console.log('-', e.message));
});
/* Output:
   All failed:
   - Error 1
   - Error 2
*/

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

如果侵犯了你的权益请来信告知我们删除。邮箱: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 ☕.