使用 JS 模块模式在回调函数中设置变量

Set variable within callback function with JS module pattern

我正在使用 YouTube iframe api 加载视频,然后我可以对其执行操作。

我正在使用 browserify 来创建模块化行为,并正在使用 JS 模块模式来分解我的代码。

当我使用 YouTubeIframeLoader 启动 createYT 函数时,我会在其回调中创建 YT.Player 的实例。

我想将 YT.Player 分配给一个我可以在模块的其他函数中访问的变量。这是我到目前为止

const videos = {
   init: function() {
      this.loadYT();
      this.changeVid();
   },
   loadYT: function() {
      YouTubeIframeLoader.load(function(YT) {
        var player = new YT.Player('video-placeholder', {
          height: '390',
          width: '640',
          videoId: 'fObfRDB0JQw'
        });
      });
   },
   changeVid: function() {
       // access player var to perform methods on YT.Player instance
   }
};

export default videos;

I would like to assign the YT.Player to a variable that I can access in other functions of my module.

这个问题的解决方案非常简单:在模块的 outer-most 范围内声明一个变量,并在 loadYT 范围内为其赋值。例如:

// Declare `player` here instead
let player;

const videos = {
   //...
   loadYT: function() {
      YouTubeIframeLoader.load(function(YT) {
        // Assign value to `player`
        player = new YT.Player('video-placeholder', {
          height: '390',
          width: '640',
          videoId: 'fObfRDB0JQw'
        });
      });
   },
   changeVid: function() {
       if (player) {
           // Use `player` here...
       }
       else {
           // Handle `player` not initialised... or throw an Error
           throw new Error('player not initialised');
       }
   }
};

export default videos;

正如@RGraham 在他的评论中提到的那样,您可能想要更改 init 的行为,使其 returns 一个 Promise 当回调给予 YouTubeIframeLoader.load 被调用。通过这种方式,您可以确保在 then 回调中使用剩余的 API(例如 changeVid)时初始化已完成。

let resolve, reject, promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
});    

let initialised = false;
let player;

const videos = {
   init: function() {
       if (!initialised) this.loadYT();
       return promise;
   },
   loadYT: function() {
      YouTubeIframeLoader.load(function(YT) {
        // Assign value to `player`
        player = new YT.Player('video-placeholder', {
          height: '390',
          width: '640',
          videoId: 'fObfRDB0JQw'
        });
        initialised = true;
        resolve();
      });
      return promise;
   },
   changeVid: function() {
       if (player) {
           // Use `player` here...
       }
       else {
           // Handle `player` not initialised... or throw an Error
           throw new Error('player not initialised');
       }
   }
};

export default videos;

用法示例:

videos.init().then(() => {
    videos.changeVid();
});