The static methods of Promise
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
下一篇:Promise的微任务队列特性