【问题标题】:Set variable within callback function with JS module pattern使用 JS 模块模式在回调函数中设置变量
【发布时间】:2016-01-05 11:47:50
【问题描述】:

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

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

当我启动createYT 函数时,我使用YouTubeIframeLoader 在其回调中创建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;

【问题讨论】:

  • 除了现有的答案,别忘了YouTubeIframeLoader.load 是一个回调,所以你可能无法调用loadYTchangeVid相继。在此处使用 Promise
  • 嗯,这很有道理,使用这种模式实现承诺的最佳方式是什么?

标签: javascript youtube-api ecmascript-6 module-pattern youtube-iframe-api


【解决方案1】:

我想将YT.Player 分配给我可以在模块的其他函数中访问的变量。

解决方案非常简单:在模块的最外层范围内声明一个变量,并在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 的行为,使其返回一个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();
});

【讨论】:

    猜你喜欢
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2018-10-10
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多