You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现适配浏览器与Node.js的通用Promise处理类?

实现跨浏览器与Node.js环境兼容的Promise处理模块

我来帮你搞定这个跨环境兼容的问题!你已经完成了移除DOM操作的关键步骤,接下来只需要调整模块的导出逻辑,同时优化一下代码里的this绑定,就能让这套Promise处理类完美运行在浏览器和Node.js环境中了。

核心改造思路

  • 双模块系统兼容:同时支持ES模块(import/export)和CommonJS(require/module.exports),覆盖浏览器和Node.js的加载需求
  • 简化this绑定:用箭头函数替代bind(this),让代码更简洁易读
  • 保留核心功能:不改动Process、ProcessQueue、ProcessStatus的核心业务逻辑,只调整环境适配部分

修改后的完整代码

ProcessStatus.js

const ProcessStatus = Object.freeze({
  INPROGRESS: 'INPROGRESS',
  SUCCESS: 'SUCCESS',
  FAILED: 'FAILED'
});

// 兼容CommonJS(Node.js)和浏览器全局变量
if (typeof module !== 'undefined' && module.exports) {
  module.exports = ProcessStatus;
} else {
  window.ProcessStatus = ProcessStatus;
}

// 保留ES模块导出
export default ProcessStatus;

Process.js

import ProcessStatus from './ProcessStatus';

class Process {
  constructor(invoker) {
    if (invoker instanceof Function) {
      this._promise = new Promise(invoker);
    } else if (invoker instanceof Promise) {
      this._promise = invoker;
    } else {
      throw new TypeError('Invalid invoker passed for Process constructor');
    }
    this._status = ProcessStatus.INPROGRESS;
    
    // 用箭头函数自动绑定this,替代bind(this)
    this._promise.then(() => {
      this._status = ProcessStatus.SUCCESS;
    }, () => {
      this._status = ProcessStatus.FAILED;
    });
  }

  then(resolve, reject) {
    return this._promise.then(resolve, reject);
  }

  catch(reject) {
    return this._promise.catch(reject);
  }

  getStatus() {
    return this._status;
  }
}

// 兼容CommonJS和浏览器全局变量
if (typeof module !== 'undefined' && module.exports) {
  module.exports = Process;
} else {
  window.Process = Process;
}

// 保留ES模块导出
export default Process;

ProcessQueue.js

import ProcessStatus from './ProcessStatus';
import Process from './Process';

class ProcessQueue {
  constructor() {
    this._status = ProcessStatus.INPROGRESS;
    this._promise = new Promise((resolve, reject) => {
      this._resolve = resolve;
      this._reject = reject;
    });
    this._processList = [];
    this._resolvedCount = 0;
    this._successCount = 0;
    this._failureCount = 0;
    
    // 用箭头函数定义回调,自动绑定当前实例的this
    this._successCallback = () => {
      this._resolvedCount++;
      this._successCount++;
      if (this._resolvedCount === this._processList.length) {
        if (this._failureCount === 0) {
          this._status = ProcessStatus.SUCCESS;
          this._resolve();
        } else {
          this._status = ProcessStatus.FAILED;
          this._reject();
        }
      }
    };

    this._failureCallback = () => {
      this._resolvedCount++;
      this._failureCount++;
      if (this._resolvedCount === this._processList.length) {
        this._status = ProcessStatus.FAILED;
        this._reject();
      }
    };
  }

  push(process) {
    if (process instanceof Process || process instanceof ProcessQueue) {
      process.then(this._successCallback, this._failureCallback);
    } else {
      throw new TypeError('Invalid process type pushed to the queue');
    }
    this._processList.push(process);
  }

  then(resolve, reject) {
    return this._promise.then(resolve, reject);
  }

  catch(reject) {
    return this._promise.catch(reject);
  }

  getStatus() {
    return this._status;
  }
}

// 兼容CommonJS和浏览器全局变量
if (typeof module !== 'undefined' && module.exports) {
  module.exports = ProcessQueue;
} else {
  window.ProcessQueue = ProcessQueue;
}

// 保留ES模块导出
export default ProcessQueue;

跨环境使用方式

在Node.js环境(CommonJS)

const Process = require('./Process');
const ProcessQueue = require('./ProcessQueue');
const ProcessStatus = require('./ProcessStatus');

// 示例使用
const testProcess = new Process((resolve) => setTimeout(resolve, 1000));
const queue = new ProcessQueue();
queue.push(testProcess);
queue.then(() => console.log(queue.getStatus()));

在浏览器环境

  • ES模块方式(现代浏览器):
<script type="module">
  import Process from './Process.js';
  import ProcessQueue from './ProcessQueue.js';
  import ProcessStatus from './ProcessStatus.js';

  // 示例使用
  const testProcess = new Process((resolve) => setTimeout(resolve, 1000));
  const queue = new ProcessQueue();
  queue.push(testProcess);
  queue.then(() => console.log(queue.getStatus()));
</script>
  • 传统全局变量方式:
<script src="./ProcessStatus.js"></script>
<script src="./Process.js"></script>
<script src="./ProcessQueue.js"></script>
<script>
  // 直接使用全局变量
  const testProcess = new Process((resolve) => setTimeout(resolve, 1000));
  const queue = new ProcessQueue();
  queue.push(testProcess);
  queue.then(() => console.log(queue.getStatus()));
</script>

内容的提问来源于stack exchange,提问作者Abhay Jatin Doshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:47:41