isPromise
检查值是否为Promise类型。
基础用法
typescript
import { isPromise } from 'radash'
console.log(isPromise(Promise.resolve(123))) // true
console.log(isPromise(new Promise(() => {}))) // true
console.log(isPromise(Promise.reject('error'))) // true
console.log(isPromise({})) // false
console.log(isPromise([])) // false
console.log(isPromise(() => {})) // false
语法
typescript
function isPromise(value: any): value is Promise<any>
参数
value
(any): 要检查的值
返回值
返回一个布尔值,如果值是Promise对象则返回 true
,否则返回 false
。同时作为TypeScript类型守卫。
示例
基本类型检查
typescript
import { isPromise } from 'radash'
// Promise对象
console.log(isPromise(Promise.resolve(123))) // true
console.log(isPromise(new Promise(() => {}))) // true
console.log(isPromise(Promise.reject('error'))) // true
console.log(isPromise(Promise.all([]))) // true
console.log(isPromise(Promise.race([]))) // true
// 非Promise对象
console.log(isPromise({})) // false
console.log(isPromise([])) // false
console.log(isPromise(() => {})) // false
console.log(isPromise('hello')) // false
console.log(isPromise(123)) // false
console.log(isPromise(true)) // false
console.log(isPromise(null)) // false
console.log(isPromise(undefined)) // false
自定义Promise检查
typescript
import { isPromise } from 'radash'
// 自定义Promise-like对象
const customPromise = {
then: (resolve: any) => resolve('custom'),
catch: () => {}
}
console.log(isPromise(customPromise)) // false
// 真正的Promise
const realPromise = Promise.resolve('real')
console.log(isPromise(realPromise)) // true
类型守卫使用
typescript
import { isPromise } from 'radash'
async function processValue(value: unknown) {
if (isPromise(value)) {
// TypeScript 知道 value 是 Promise
console.log('Processing Promise')
return await value
}
console.log('Processing non-Promise:', typeof value)
return value
}
const promise = Promise.resolve('hello')
const nonPromise = 'world'
console.log(await processValue(promise)) // Processing Promise hello
console.log(await processValue(nonPromise)) // Processing non-Promise: string world
数组过滤
typescript
import { isPromise } from 'radash'
const mixedArray = [
Promise.resolve(1),
'hello',
123,
Promise.reject('error'),
{ then: () => {} },
new Promise(() => {}),
() => {},
[]
]
const promises = mixedArray.filter(isPromise)
console.log(promises.length) // 3
const nonPromises = mixedArray.filter(item => !isPromise(item))
console.log(nonPromises.length) // 5
异步函数处理
typescript
import { isPromise } from 'radash'
function handleAsyncOperation(operation: unknown) {
if (isPromise(operation)) {
return operation.then(result => {
console.log('Promise resolved:', result)
return result
}).catch(error => {
console.log('Promise rejected:', error)
throw error
})
}
console.log('Non-Promise operation:', operation)
return Promise.resolve(operation)
}
const promiseOp = Promise.resolve('success')
const syncOp = 'immediate'
handleAsyncOperation(promiseOp) // Promise resolved: success
handleAsyncOperation(syncOp) // Non-Promise operation: immediate
API响应处理
typescript
import { isPromise } from 'radash'
interface ApiResponse {
data: unknown
error: unknown
promise: unknown
}
async function processApiResponse(response: ApiResponse) {
const processed = {
data: isPromise(response.data) ? await response.data : response.data,
error: isPromise(response.error) ? await response.error : response.error,
promise: isPromise(response.promise) ? response.promise : Promise.resolve(response.promise)
}
return processed
}
const response: ApiResponse = {
data: Promise.resolve({ id: 1, name: 'Alice' }),
error: null,
promise: 'not a promise'
}
console.log(await processApiResponse(response))
// { data: { id: 1, name: 'Alice' }, error: null, promise: Promise { 'not a promise' } }
函数包装
typescript
import { isPromise } from 'radash'
function wrapWithPromise<T>(value: T | Promise<T>): Promise<T> {
if (isPromise(value)) {
return value
}
return Promise.resolve(value)
}
async function example() {
const syncValue = 'hello'
const asyncValue = Promise.resolve('world')
const wrapped1 = wrapWithPromise(syncValue)
const wrapped2 = wrapWithPromise(asyncValue)
console.log(await wrapped1) // hello
console.log(await wrapped2) // world
}
example()
错误处理
typescript
import { isPromise } from 'radash'
async function safeExecute(operation: unknown) {
try {
if (isPromise(operation)) {
return await operation
}
return operation
} catch (error) {
console.log('Error occurred:', error)
return null
}
}
const successPromise = Promise.resolve('success')
const errorPromise = Promise.reject('error')
const syncValue = 'hello'
console.log(await safeExecute(successPromise)) // success
console.log(await safeExecute(errorPromise)) // Error occurred: error null
console.log(await safeExecute(syncValue)) // hello
批量处理
typescript
import { isPromise } from 'radash'
async function processBatch(operations: unknown[]) {
const results = []
for (const operation of operations) {
if (isPromise(operation)) {
try {
const result = await operation
results.push({ success: true, data: result })
} catch (error) {
results.push({ success: false, error })
}
} else {
results.push({ success: true, data: operation })
}
}
return results
}
const batch = [
Promise.resolve('success1'),
'immediate',
Promise.reject('error1'),
Promise.resolve('success2'),
123
]
console.log(await processBatch(batch))
// [
// { success: true, data: 'success1' },
// { success: true, data: 'immediate' },
// { success: false, error: 'error1' },
// { success: true, data: 'success2' },
// { success: true, data: 123 }
// ]
条件执行
typescript
import { isPromise } from 'radash'
async function conditionalExecute(condition: unknown, operation: unknown) {
if (isPromise(condition)) {
const shouldExecute = await condition
if (shouldExecute) {
return isPromise(operation) ? await operation : operation
}
} else if (condition) {
return isPromise(operation) ? await operation : operation
}
return null
}
const trueCondition = Promise.resolve(true)
const falseCondition = Promise.resolve(false)
const syncCondition = true
const operation = Promise.resolve('executed')
console.log(await conditionalExecute(trueCondition, operation)) // executed
console.log(await conditionalExecute(falseCondition, operation)) // null
console.log(await conditionalExecute(syncCondition, operation)) // executed
超时处理
typescript
import { isPromise } from 'radash'
async function withTimeout<T>(promise: T | Promise<T>, timeoutMs: number): Promise<T> {
if (!isPromise(promise)) {
return promise
}
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => reject(new Error('Timeout')), timeoutMs)
})
return Promise.race([promise, timeoutPromise])
}
const slowPromise = new Promise(resolve => {
setTimeout(() => resolve('slow result'), 2000)
})
const fastPromise = Promise.resolve('fast result')
try {
console.log(await withTimeout(slowPromise, 1000)) // Error: Timeout
} catch (error) {
console.log('Timeout occurred')
}
console.log(await withTimeout(fastPromise, 1000)) // fast result
重试机制
typescript
import { isPromise } from 'radash'
async function withRetry<T>(
operation: T | Promise<T>,
maxRetries: number = 3,
delay: number = 1000
): Promise<T> {
if (!isPromise(operation)) {
return operation
}
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation
} catch (error) {
if (attempt === maxRetries) {
throw error
}
await new Promise(resolve => setTimeout(resolve, delay))
}
}
throw new Error('Max retries exceeded')
}
const failingPromise = new Promise((_, reject) => {
setTimeout(() => reject('Failed'), 100)
})
const successPromise = Promise.resolve('Success')
try {
console.log(await withRetry(successPromise)) // Success
console.log(await withRetry(failingPromise, 3, 100)) // Error after 3 attempts
} catch (error) {
console.log('All retries failed:', error)
}
缓存机制
typescript
import { isPromise } from 'radash'
class PromiseCache {
private cache = new Map<string, Promise<any>>()
async getOrCreate<T>(
key: string,
factory: () => T | Promise<T>
): Promise<T> {
if (this.cache.has(key)) {
return this.cache.get(key)!
}
const promise = factory()
if (isPromise(promise)) {
this.cache.set(key, promise)
return promise
}
const resolvedPromise = Promise.resolve(promise)
this.cache.set(key, resolvedPromise)
return resolvedPromise
}
clear() {
this.cache.clear()
}
}
const cache = new PromiseCache()
async function expensiveOperation(id: string) {
console.log(`Executing expensive operation for ${id}`)
await new Promise(resolve => setTimeout(resolve, 1000))
return `Result for ${id}`
}
// 第一次调用会执行操作
console.log(await cache.getOrCreate('user1', () => expensiveOperation('user1')))
// 第二次调用会使用缓存
console.log(await cache.getOrCreate('user1', () => expensiveOperation('user1')))
并发控制
typescript
import { isPromise } from 'radash'
class ConcurrencyLimiter {
private running = 0
private queue: Array<() => Promise<any>> = []
constructor(private maxConcurrency: number) {}
async execute<T>(operation: T | Promise<T>): Promise<T> {
if (!isPromise(operation)) {
return operation
}
if (this.running >= this.maxConcurrency) {
return new Promise((resolve, reject) => {
this.queue.push(async () => {
try {
const result = await operation
resolve(result)
} catch (error) {
reject(error)
}
})
})
}
this.running++
try {
const result = await operation
return result
} finally {
this.running--
if (this.queue.length > 0) {
const next = this.queue.shift()!
next()
}
}
}
}
const limiter = new ConcurrencyLimiter(2)
async function simulateWork(id: number) {
console.log(`Starting work ${id}`)
await new Promise(resolve => setTimeout(resolve, 1000))
console.log(`Completed work ${id}`)
return `Result ${id}`
}
// 并发执行,但最多同时运行2个
const promises = Array.from({ length: 5 }, (_, i) =>
limiter.execute(simulateWork(i + 1))
)
console.log(await Promise.all(promises))
事件处理
typescript
import { isPromise } from 'radash'
class EventHandler {
private handlers: Array<(...args: any[]) => any | Promise<any>> = []
addHandler(handler: (...args: any[]) => any | Promise<any>) {
this.handlers.push(handler)
}
async emit(...args: any[]) {
const results = []
for (const handler of this.handlers) {
const result = handler(...args)
if (isPromise(result)) {
try {
results.push(await result)
} catch (error) {
results.push({ error })
}
} else {
results.push(result)
}
}
return results
}
}
const eventHandler = new EventHandler()
eventHandler.addHandler((data) => {
console.log('Sync handler:', data)
return 'sync result'
})
eventHandler.addHandler(async (data) => {
console.log('Async handler:', data)
await new Promise(resolve => setTimeout(resolve, 100))
return 'async result'
})
eventHandler.emit('test data').then(results => {
console.log('All handlers completed:', results)
})
性能测试
typescript
import { isPromise } from 'radash'
function benchmarkIsPromise() {
const testValues = [
Promise.resolve(1),
Promise.reject('error'),
new Promise(() => {}),
{},
[],
() => {},
'hello',
123,
true,
null,
undefined
]
const iterations = 1000000
const start = performance.now()
for (let i = 0; i < iterations; i++) {
testValues.forEach(value => {
isPromise(value)
})
}
const end = performance.now()
console.log(`Benchmark completed in ${end - start}ms`)
}
// benchmarkIsPromise() // 运行性能测试
注意事项
- Promise检测: 准确检测真正的Promise对象
- 类型守卫: 作为TypeScript类型守卫使用
- 性能: 检查速度很快,适合高频使用
- 边界值: 正确处理所有边界情况
- 自定义Promise: 不检测Promise-like对象
与其他方法的区别
isPromise()
: 检查是否为Promise对象value instanceof Promise
: 原生JavaScript检查typeof value === 'object' && value !== null && typeof value.then === 'function'
: 手动检查value && typeof value.then === 'function'
: 简单但不够准确
实际应用场景
- 异步处理: 处理可能返回Promise的函数
- API调用: 处理异步API响应
- 错误处理: 统一处理同步和异步错误
- 缓存机制: 缓存Promise结果
- 并发控制: 限制并发Promise数量
- 事件处理: 处理异步事件处理器