xDocxDoc
AI
前端
后端
iOS
Android
Flutter
AI
前端
后端
iOS
Android
Flutter
  • JavaScript Promise 方法全解

JavaScript Promise 方法全解:构建健壮的异步应用

一、Promise核心静态方法深度剖析

1.1 Promise.all() - 全有或全无

核心机制:

// 所有Promise成功时返回结果数组
const allSuccess = Promise.all([
  fetch('/api/users'),
  fetch('/api/products'),
  fetch('/api/orders')
]);

allSuccess.then(([users, products, orders]) => {
  // 所有数据可用后才渲染页面
  renderDashboard(users, products, orders); 
}).catch(err => {
  // 任一请求失败即中断
  showError('数据加载不完整'); 
});

技术细节:

  • 返回按输入顺序排列的结果数组
  • 短路特性:首个拒绝立即触发catch
  • 适合强依赖场景:支付流程、表单多步骤提交

真实案例:电商订单创建流程

const createOrder = Promise.all([
  validateCart(),
  checkInventory(),
  reservePayment()
]);

createOrder.then(([validation, inventory, payment]) => {
  // 所有前置条件满足后才创建订单
  finalizeOrder(validation.cartId, payment.transactionId);
});

1.2 Promise.race() - 竞速模式

核心机制:

// 获取首个响应的CDN资源
const resourceRace = Promise.race([
  fetch('https://cdn1.example.com/asset.js'),
  fetch('https://cdn2.example.com/asset.js'),
  new Promise((_, reject) => 
    setTimeout(() => reject(new Error('Timeout')), 5000)
  )
]);

resourceRace.then(script => injectToDOM(script))
  .catch(() => loadFallbackResource());

技术细节:

  • 无论成功/失败都返回首个settled结果
  • 常用超时控制:race(fetchRequest, timeoutPromise)
  • 适用场景:性能优化、服务降级

物联网案例:多传感器数据采集

const sensorRace = Promise.race([
  readTemperatureSensor(),
  readHumiditySensor(),
  readMotionSensor()
]);

sensorRace.then(firstData => {
  // 首个响应的传感器触发警报判断
  if(firstData.value > threshold) triggerAlarm();
});

1.3 Promise.any() - 成功优先

核心机制(详见前文):

// 多地域服务容灾
Promise.any([
  fetch('https://us-east.api.service.com'),
  fetch('https://eu-west.api.service.com'),
  fetch('https://asia-southeast.api.service.com')
]).then(firstResponse => processData(firstResponse));

进阶技巧:

// 带优先级的any实现
function priorityAny(promises, priorities) {
  return new Promise((resolve, reject) => {
    let completed = 0;
    const errors = [];
    
    promises.forEach((promise, i) => {
      promise.then(res => {
        if(priorities[i] === 'high') resolve(res); // 高优先级立即返回
        completed++;
        if(completed === promises.length) resolve(res);
      }).catch(err => {
        errors.push(err);
        if(errors.length === promises.length) {
          reject(new AggregateError(errors));
        }
      });
    });
  });
}

1.4 Promise.allSettled() - 全生命周期管理

核心机制:

// 批量用户操作状态追踪
const userActions = Promise.allSettled([
  saveProfileChanges(),
  updateBillingInfo(),
  syncPreferences()
]);

userActions.then(results => {
  results.forEach((result, index) => {
    if(result.status === 'fulfilled') {
      logSuccess(`操作${index}成功`, result.value);
    } else {
      logError(`操作${index}失败`, result.reason);
    }
  });
});

技术价值:

  • 获取每个Promise的完整生命周期状态
  • 无短路特性,适合非关键路径操作
  • 错误恢复友好:部分失败不影响整体流程

二、Promise实例方法高阶实践

2.1 then() - 链式调用的艺术

核心技术:

// 多步骤异步流水线
getUserToken()
  .then(token => fetchUserData(token))
  .then(user => {
    if(!user.profileComplete) {
      // 返回新Promise实现条件分支
      return completeProfile(user); 
    }
    return user;
  })
  .then(finalizeAuth)
  .catch(handleAuthError);

内存优化技巧:

// 避免闭包内存泄漏
processLargeData()
  .then(data => {
    const processed = heavyCompute(data);
    // 及时释放原始数据引用
    return Promise.resolve(processed).finally(() => data = null);
  });

2.2 catch() - 错误处理金字塔

分层错误处理:

networkRequest()
  .catch(networkError => {
    // 网络层错误恢复
    return cachedVersion(); 
  })
  .then(processContent)
  .catch(contentError => {
    // 业务逻辑错误处理
    if(contentError.code === 403) {
      return requestPermission();
    }
    throw contentError; // 重新抛出
  })
  .finally(cleanupResources);

2.3 finally() - 资源管理利器

原子操作保障:

let dbConnection;
openDatabase()
  .then(conn => {
    dbConnection = conn;
    return executeTransaction(conn);
  })
  .finally(() => {
    // 无论成功失败都释放连接
    if(dbConnection && !dbConnection.isClosed) {
      dbConnection.release();
    }
  });

三、Promise高级模式与性能优化

3.1 并发控制:避免Promise.all爆炸

// 通用并发控制器
function promisePool(tasks, concurrency) {
  let index = 0;
  const results = [];
  const workers = Array(concurrency).fill().map(async () => {
    while(index < tasks.length) {
      const currentIndex = index++;
      try {
        results;
      } catch(err) {
        results[currentIndex] = err;
      }
    }
  });
  return Promise.all(workers).then(() => results);
}

// 控制10个并发下载
const downloadQueue = promisePool(
  Array(100).fill().map((_, i) => () => downloadFile(`file${i}.zip`)),
  10
);

3.2 取消架构:AbortController集成

// 可取消的Promise包装器
function cancellablePromise(executor) {
  const controller = new AbortController();
  const promise = new Promise((resolve, reject) => {
    executor(resolve, reject, controller.signal);
    
    // 监听取消信号
    controller.signal.addEventListener('abort', () => {
      reject(new DOMException('Aborted', 'AbortError'));
    });
  });
  
  return Object.assign(promise, {
    cancel: () => controller.abort()
  });
}

// 使用示例
const searchRequest = cancellablePromise((resolve, reject, signal) => {
  fetch('/search', { signal })
    .then(resolve)
    .catch(reject);
});

// 用户取消搜索
searchInput.addEventListener('input', () => {
  if(searchRequest) searchRequest.cancel();
});

四、Promise与现代异步模式对比

4.1 Promise vs async/await

// Promise链
function fetchSequential() {
  return fetchUser()
    .then(user => fetchProfile(user.id))
    .then(profile => fetchPosts(profile.id));
}

// async/await等效实现
async function fetchSequentialAsync() {
  const user = await fetchUser();
  const profile = await fetchProfile(user.id);
  return fetchPosts(profile.id);
}

混合使用最佳实践:

async function loadDashboard() {
  try {
    // 并行独立请求
    const [user, notifications] = await Promise.all([
      fetchUser(),
      fetchNotifications()
    ]);
    
    // 顺序依赖请求
    const permissions = await fetchPermissions(user.role);
    
    return { user, notifications, permissions };
  } catch(err) {
    if(err.name === 'AbortError') {
      console.log('Request cancelled');
    } else {
      reportError(err);
    }
  }
}

4.2 Promise vs Observable (RxJS)

特性PromiseObservable
数据流单值多值流
取消支持⚠️ 需手动实现✅ 内置
背压处理❌✅ 内置
重试机制⚠️ 需手动封装✅ retry操作符
响应式编程❌✅ 完整支持
// RxJS实现竞速请求
import { race, timer } from 'rxjs';
import { mapTo } from 'rxjs/operators';

race(
  fetch('/api/primary'),
  timer(5000).pipe(mapTo({ data: 'fallback' }))
).subscribe(result => handleResponse(result));

五、Promise调试与性能监控

5.1 未处理拒绝追踪

// 全局未捕获Promise错误
window.addEventListener('unhandledrejection', event => {
  console.error('Unhandled rejection:', event.reason);
  event.preventDefault(); // 阻止默认控制台报错
  
  // 上报错误日志
  logErrorToService({
    type: 'UNHANDLED_REJECTION',
    error: event.reason
  });
});

5.2 性能分析工具

// Promise执行时间监控
const timedPromise = fn => (...args) => {
  const start = performance.now();
  return fn(...args).finally(() => {
    const duration = performance.now() - start;
    if(duration > 1000) {
      reportSlowPromise(fn.name, duration);
    }
  });
};

// 使用示例
const monitoredFetch = timedPromise(fetch);
monitoredFetch('/api/slow-endpoint');

六、Promise的现代化替代方案

6.1 原生异步队列:queueMicrotask

// Promise.resolve().then()的底层实现
function scheduleTask(fn) {
  if(typeof queueMicrotask === 'function') {
    queueMicrotask(fn);
  } else {
    Promise.resolve().then(fn);
  }
}

6.2 浏览器原生模块:Web Locks API

// 资源互斥锁管理
navigator.locks.request('cache-flush', async lock => {
  // 类似Promise的异步作用域
  await flushCache();
  await rebuildIndex();
});

6.3 新兴标准:Async Context Tracking

// 提案:https://github.com/tc39/proposal-async-context
const context = new AsyncLocalStorage();

function processRequest(req) {
  return context.run(req, async () => {
    // 整个异步链路共享上下文
    await verifyAuth();
    await loadData();
    return generateResponse();
  });
}

总结:构建Promise驱动的健壮应用

🛠️ 方法选择决策树

💡 架构最佳实践

  1. 分层错误处理:为不同层级(网络/业务/基础设施)实现独立catch
  2. 资源生命周期:finally中统一释放连接/文件句柄
  3. 并发治理:动态控制并行数量,避免资源耗尽
  4. 可观察性:添加监控指标(成功率/延迟/取消率)
  5. 渐进增强:配合polyfill实现跨环境兼容

🔭 未来演进方向

  • 异步上下文:解决全链路追踪难题
  • 结构化并发:原生支持作用域管理(如Node.js AsyncResource)
  • WebAssembly集成:Promise与wasm的互操作优化
  • 跨线程通信:配合SharedArrayBuffer实现高效线程间Promise

最终目标:通过Promise将异步复杂度封装为标准接口,让开发者专注业务价值而非流程控制 🚀

最后更新: 2025/9/1 14:41