【问题标题】:play() promise doesn't resolveplay() 承诺没有解决
【发布时间】:2020-01-22 23:51:01
【问题描述】:

我的网站上有多个视频需要播放()。 由于 play() 返回了一个 Promise,我使用 Promise.all() 创建了一个小脚本,因此每个 Promise 都在等待其他 Promise。

try {
    var fn = function playVideo(element) {
        var newPromise = element.play();
        console.log('PROMISE', newPromise); // promise is returned (but not yet resolved)
        return newPromise;
    };

    var promise = this.videos.map(fn);
    var results = Promise.all(promise); // all promises should resolve

    results.then(data =>
        console.log('DATA', data)
    ), (err => {
        console.log('error', err);
    });
}
catch(err) {
    console.log('err', err);
}

this.videos 是一个视频数组,我这样定义:

var getVideos = document.querySelectorAll('.project__video .video-js');

if(getVideos.length === 0) {
    return;
}

Array.from(getVideos).forEach((element) => {
    try {
        const autoplay = !element.classList.contains('video-nonplay');
        const controls = !autoplay;
        const muted = autoplay;
        const loop = autoplay;

        const video = window.videojs(element, {
            controls,
            autoplay: false,
            preload: 'none',
            muted,
            fluid: true,
            playsinline: true,
            loop
        });

        if (autoplay) {
            this.videos.push(video);
        }
    }
    catch(err) {
        console.log('error while initiating video!', err);
    }
});

我希望 Promise.all() 能够兑现我的承诺,但当我 console.log(data) 时,我在 Chrome/Safar 中得到一个未定义 2x 的数组,而在 Firefox 中根本没有返回(.then 从未被调用?)。

这种承诺解决方法是否不适用于 .play() 还是我做错了?

编辑 1

刚刚注意到,在 Chrome/Safari 中,视频播放实际上已经开始,即使 promise 没有解决。在 Firefox 中播放不开始。

编辑 2

尝试实现 Josh Kelly 的解决方案如下:

创建了一个名为playVideos的单独函数

playVideos(videos) {
    try {
        const playVideo = (el) => el.play();
        return videos.map(playVideo);
    } catch(err) {
        console.log('err', err);
    }
}

我这样称呼它

var vids = this.playVideos(this.videos);
console.log('returned vids', vids);

在控制台日志中,我可以看到 chrome 已经解决了 promise,而 firefox(和 IE/EdgeHTML)还没有。

【问题讨论】:

  • 我会解决 playVideo() 内部的承诺并返回它。然后您可以删除Promise.all() 并返回结果。
  • 我尝试使用Promise.resolve(newPromise);,但没有任何改变。文档还说,当播放开始时,承诺应该自动解决:developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play
  • 您希望在data 中出现什么?根据video.js docs.play() 返回的 Promise 无法解决任何问题,因此需要记录 undefined。你用的是哪个火狐版本?
  • @Klaycon 不应该 data 返回承诺本身吗?所以使用console.log(data) 我应该看看承诺是否得到履行/解决。目前不是(请参阅下面的答案中的 EDIT 2 和 cmets)
  • @Toby 阅读 Promise.all 上的文档 - 它接受一个承诺数组,并返回一个承诺,该承诺将在所有完成后用承诺解决的所有值的数组进行解析。

标签: javascript promise video.js


【解决方案1】:

你不能在下面做这样的事情吗?

隐式返回应该为您解决承诺,然后您可以返回 videos 并传入 playVideo() 方法。

try {
  const playVideo = (el) => el.play()

  return this.videos.map(playVideo)
} catch(err) {
  console.log('err', err);
}

【讨论】:

  • 我在 Chrome 和 Firefox 中有不同的行为(如我上面的编辑中所述)。 Chrome 确实解决了 promise 和 play()。 Firefox 没有解决这个承诺。我会用你的代码更新我的问题,这样你就可以看到我是如何尝试实现它的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-20
  • 2022-01-16
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 2021-12-20
相关资源
最近更新 更多