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

如何确保动态加载的脚本在调用指定函数前完全加载?

解决Angular动态脚本加载与用户操作时序冲突问题

核心思路

通过Promise跟踪脚本加载状态,让按钮点击逻辑等待脚本完全加载(含加载失败场景)后再执行,同时搭配UI层面的禁用控制,从根源避免用户在脚本未就绪时触发操作。

具体实现步骤

1. 组件内维护脚本加载状态变量

在组件类中添加用于跟踪加载状态的Promise和UI控制变量:

import { Component, OnInit, OnDestroy, Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

export class HomeComponent implements OnInit, OnDestroy {
  private script: any;
  private scriptLoadedPromise: Promise<void>; // 跟踪脚本加载完成状态
  public isScriptLoaded = false; // 用于控制按钮禁用状态

  constructor(
    private _renderer2: Renderer2,
    @Inject(DOCUMENT) private _document: Document
  ) {}

2. 把脚本加载封装成Promise

修改insertDynamicallyScript方法,将脚本加载过程包装为Promise,确保加载成功/失败时都能触发状态变更:

public insertDynamicallyScript(): void {
  this.scriptLoadedPromise = new Promise((resolve, reject) => {
    this.script = this._renderer2.createElement('script');
    this.script.type = 'text/javascript';
    this.script.src = 'url.here';
    this.script.async = false;

    // 脚本加载成功回调
    this.script.onload = () => {
      console.log('Script loaded');
      this.isScriptLoaded = true;
      resolve();
    };

    // 脚本加载失败回调,避免Promise一直处于pending状态
    this.script.onerror = (error: ErrorEvent) => {
      console.error('Script load failed:', error);
      reject(new Error('Required script failed to load'));
    };

    this._renderer2.appendChild(this._document.body, this.script);
  });
}

3. 修改按钮点击函数,等待脚本加载完成

在userButtonActionFunction中先等待脚本加载Promise完成,再执行业务逻辑:

public async userButtonActionFunction(): Promise<void> {
  try {
    // 等待脚本加载完成,加载失败会直接进入catch块
    await this.scriptLoadedPromise;
    
    if (window['scriptFunction']) {
      await window['scriptFunction'].doSomething();
    } else {
      console.error('Script loaded but target function not found');
      // 这里可添加用户友好提示,比如弹窗告知功能暂时不可用
    }
  } catch (exception) {
    console.error('Error during script operation:', exception);
    // 处理脚本加载失败或执行出错的情况,比如显示错误提示
  } finally {
    // 无论成功失败都要执行的逻辑
  }
}

4. (可选)UI层面禁用按钮

在模板中给按钮绑定禁用状态,直到脚本加载完成才允许点击:

<button 
  (click)="userButtonActionFunction()"
  [disabled]="!isScriptLoaded"
>
  {{ isScriptLoaded ? '执行操作' : '加载中...' }}
</button>

额外注意事项

  • 修正原代码语法错误:类成员定义不需要加this.,比如把this.script: any;改为private script: any;;
  • 确保DOCUMENT从@angular/common导入,避免依赖注入报错;
  • 可添加重复加载判断:插入脚本前先检查window['scriptFunction']是否已存在,避免重复插入脚本;
  • 脚本加载失败时要给出明确的用户提示,提升体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:20:15