繁体   English   中英

仅在执行Javascript递归函数后才启用Jquery

[英]Enable Jquery Only after Javascript recursive function is done executing

//image sequence functions
//preload array
/**
 * Preload images in a directory.
 * @param {string} baseurl 
 * @param {string} extension
 * @return {Promise} resolve an Array<Image>.
 */
function preloadImages(baseurl, extension, starter) {
    return new Promise(function (res) {
        var i = starter;
        var images = [];
        // Inner promise handler
        var handler = function (resolve, reject) {
            var img = new Image;
            var source = baseurl + i + '.' + extension;
            img.onload = function () {
                i++;
                resolve(img);
            }
            img.onerror = function () {
                reject('Rejected after ' + i + 'frames.');
            }
            img.src = source;
        }
        // Once you catch the inner promise you resolve the outer one.
        var _catch = function () {
            res(images)
        }
        var operate = function (value) {
            if (value) images.push(value);
            // Inner recursive promises chain.
            // Stop with the catch resolving the outer promise.
            new Promise(handler).then(operate).catch(_catch);
        }
        operate();
    })
}

/**
 * Draw an Array of images on a canvas.
 * @param {Canvas} canvas 
 * @param {Array<Image>} imagelist 
 * @param {number} refreshRate 
 */
function play(canvas, imagelist, refreshRate, frameWidth, frameHeight, percentage) {
    // Since we're using promises, let's promisify the animation too.
    return new Promise(function (resolve) {
        // May need to adjust the framerate
        // requestAnimationFrame is about 60/120 fps depending on the browser
        // and the refresh rate of the display devices.
        var ctx = canvas.getContext('2d');
        var ts, i = 0,
            delay = 1000 / refreshRate;
        var roll = function (timestamp) {
            if (!ts || timestamp - ts >= delay) {
                // Since the image was prefetched you need to specify the rect.
                ctx.drawImage(imagelist[i], 0, 0, frameWidth, frameHeight);
                i++;
                ts = timestamp;
            }
            if (i < imagelist.length * percentage)
                requestAnimationFrame(roll);
            else
                resolve(i);
        }
        roll();
    })
}
//combine preload and play into one
function preloadAndPlay(ID, actor, event, percentage) {
    var preload = preloadImages('/static/videos/' + actor + '/Clip_' + event + '/', 'png', 1);
    preload.then(function (value) {
        //console.log('starting play');
        //canvas html5 object with ID
        var canvas = document.getElementById(ID);
        play(canvas, value, 30, 960, 540, percentage) // ~30fps
            .then(function (frame) {
                console.log('roll finished after ' + frame + ' frames.')
            })
    });
}   



$.when(preloadAndPlay('myImage', actor, event, percentage)).done(function(){
        $('.data').click(function () {
            if ($(this).is(':checked')) {
                $(this).removeClass('hidden');
                $(that).addClass('hidden');
            }
            that = this;
        });
        $('.data').change(function () {
            if (('input[name=b]:checked').length) {
                $('#trial_next').prop('disabled', false);
                cbChecked = document.querySelector('[name="b"]:checked').value;
                debug(cbChecked);
            }
        });
    });

我希望仅在preloadAndPlay javascript函数完全完成执行后才能启用.change和.click jQuery。 假设jQuery是允许选择的单选按钮。 preloadAndPlay是一个函数,该函数加载一系列图像,然后使用html5画布显示它们,因此看起来像是视频/动画。 请参阅上面的有关使用promise和递归的preloadAndPlay函数。 该代码有效,只是我不希望人们在视频结束之前进行选择。 上面是我尝试的代码。

在Question的代码中有几个问题。 preloadImages函数中,传递给Promise构造函数的函数参数名为res ,尽管在<img> load事件中在函数中调用了resolve() ,但在函数中未定义resolve 未调用handler ,未达到对未定义的resolve()调用。 Promise构造函数中不需要operate函数。 没有价值return来自ED operate ,请参阅为什么在值。然后()链接到答应未定义?

您可以使用Promise.all()来传递,其中链的迭代对象.then()所有这些值,时应该叫Promise传递的值被满足。

不确定play()调用的预期效果是什么,也不确定那部分代码是否是原始查询的一部分。 调整后的代码片段可以为每个图像调用requestAnimationFrame

 const baseurl = "https://lorempixel.com/50/50/"; const data = ["cats", "nature", "city"]; const canvas = document.querySelector("canvas"); function preloadImages(image) { return new Promise(function(resolve) { var img = new Image; var source = baseurl + image; img.onload = function() { resolve(img); } img.onerror = function() { reject('Rejected after ' + i + 'frames.'); } img.src = source; }) } function play(canvas, imagelist, refreshRate, frameWidth, frameHeight, percentage) { // Since we're using promises, let's promisify the animation too. return new Promise(function(resolve) { // May need to adjust the framerate // requestAnimationFrame is about 60/120 fps depending on the browser // and the refresh rate of the display devices. var ctx = canvas.getContext('2d'); var ts, i = 0, delay = 1000 / refreshRate; var roll = function(timestamp) { if (!ts || timestamp - ts >= delay) { // Since the image was prefetched you need to specify the rect. ctx.drawImage(imagelist[i], 0, 0, frameWidth, frameHeight); i++; ts = timestamp; } if (i < imagelist.length /* * percentage */ ) requestAnimationFrame(roll); else resolve(i); } roll(); }) } function preloadAndPlay(percentage) { var preload = Promise.all(data.map(preloadImages)) .then(function(images) { console.log("preloadImages complete, images:", images); images.forEach(function(img) { document.body.appendChild(img) }); return images }) .catch(function(err) { console.error(err); throw err; }); return preload.then(function(value) { console.log("preload complete, value:", value); return play(canvas, value, 30, 960, 540, percentage) // ~30fps .then(function(frame) { console.log('roll finished after ' + frame + ' frames.'); return "done"; }) }); } preloadAndPlay() .then(function(data) { console.log(data); }) .catch(function(err) { console.error(err) }) 
 <canvas></canvas> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM