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

如何在AutoLogout类中调用api.js的onResponse函数并正确使用回调

Solution for Resetting Token Expiry via API Response Header Without Modifying API Export

Alright, let's break down your problem and work through a couple of solid solutions that won't disrupt your existing codebase. The core issue here is accessing the x-expires-at header from API responses to reset your auto-logout timer, without altering how api is exported (since it's used everywhere) and without directly calling onResponse() from your AutoLogout class.

Option 1: Add a Lightweight Event System to the API Object

Since your api is exported as a function, we can attach simple event subscription/emission methods directly to this function object (functions are objects in JS, after all!). This lets your AutoLogout class listen for response events and act on the x-expires-at value.

Step 1: Update api.js to include event handling

// api.js
function onResponse(response) {
  // Your existing onResponse logic here...

  // Extract x-expires-at and emit an event if it exists
  const expiresAt = response.headers.get('x-expires-at');
  if (expiresAt && api.emit) {
    api.emit('token-expiry-update', expiresAt);
  }
}

// Your existing api() function definition
const api = function(apiOptions) {
  // Existing API request logic that eventually calls onResponse()
};

// Add simple event system methods to the api function
api._eventListeners = {};
api.on = function(eventName, callback) {
  if (!this._eventListeners[eventName]) {
    this._eventListeners[eventName] = [];
  }
  this._eventListeners[eventName].push(callback);
};
api.emit = function(eventName, data) {
  if (this._eventListeners[eventName]) {
    this._eventListeners[eventName].forEach(callback => callback(data));
  }
};

export default api;

Step 2: Subscribe to the Event in AutoLogout

// auto-logout.js
import api from './api.js';

class AutoLogout {
  constructor() {
    // Subscribe to the token expiry update event
    api.on('token-expiry-update', (expiresAt) => {
      this.resetTokenExpiry(expiresAt);
    });

    // Your existing AutoLogout initialization logic here...
  }

  resetTokenExpiry(expiresAt) {
    // Convert expiresAt to a timestamp and reset your auto-logout timer
    const expiryTimestamp = new Date(expiresAt).getTime();
    const timeUntilExpiry = expiryTimestamp - Date.now();
    
    // Update your timer logic here (e.g., clear existing timeout, set new one)
    this.clearAutoLogoutTimer();
    this.setAutoLogoutTimer(timeUntilExpiry);
  }

  // Your existing AutoLogout methods (clearAutoLogoutTimer, setAutoLogoutTimer, etc.)...
}

Option 2: Use Response Hooks for a Minimalist Approach

If you don't want to implement a full event system, you can add a hook system to api.js that lets you register callbacks to run when a response with x-expires-at is received.

Step 1: Add Hook Support to api.js

// api.js
const responseExpiryHooks = [];

function onResponse(response) {
  // Your existing onResponse logic here...

  const expiresAt = response.headers.get('x-expires-at');
  if (expiresAt) {
    // Run all registered hooks with the expiresAt value
    responseExpiryHooks.forEach(hook => hook(expiresAt));
  }
}

const api = function(apiOptions) {
  // Existing API request logic...
};

// Method to register hooks
api.registerExpiryHook = function(hook) {
  responseExpiryHooks.push(hook);
};

// Optional: Method to unregister hooks (useful if your AutoLogout is destroyed)
api.unregisterExpiryHook = function(hook) {
  const index = responseExpiryHooks.indexOf(hook);
  if (index !== -1) {
    responseExpiryHooks.splice(index, 1);
  }
};

export default api;

Step 2: Register the Hook in AutoLogout

// auto-logout.js
import api from './api.js';

class AutoLogout {
  constructor() {
    // Bind the hook method to preserve `this` context
    this.handleExpiryUpdate = this.resetTokenExpiry.bind(this);
    api.registerExpiryHook(this.handleExpiryUpdate);

    // Existing initialization logic...
  }

  resetTokenExpiry(expiresAt) {
    // Same logic as Option 1: update your auto-logout timer
    const expiryTimestamp = new Date(expiresAt).getTime();
    const timeUntilExpiry = expiryTimestamp - Date.now();
    
    this.clearAutoLogoutTimer();
    this.setAutoLogoutTimer(timeUntilExpiry);
  }

  // If your component/class is destroyed, clean up the hook to prevent memory leaks
  destroy() {
    api.unregisterExpiryHook(this.handleExpiryUpdate);
    this.clearAutoLogoutTimer();
  }

  // Existing methods...
}

Key Benefits of These Approaches

  • No breaking changes: Your existing api() calls remain exactly the same—we're just adding methods to the existing api function object.
  • Loose coupling: AutoLogout doesn't need direct access to onResponse(); it reacts to events/hooks triggered by the API layer.
  • Scalability: You can add other components that listen for the same expiry event if needed later.

Things to Watch For

  • Ensure x-expires-at is a valid date string (add error handling if your API might return invalid values).
  • If you instantiate AutoLogout multiple times, make sure to unregister hooks in the destroy method (Option 2) to avoid duplicate callbacks.

内容的提问来源于stack exchange,提问作者Valay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:20:47