简体   繁体   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);
            }
        });
    });

I would like the .change and .click jquery to be only enabled after preloadAndPlay javascript function is COMPLETELY done executing. 我希望仅在preloadAndPlay javascript函数完全完成执行后才能启用.change和.click jQuery。 Jquery is are suppose to be allow radio buttons that can be selected. 假设jQuery是允许选择的单选按钮。 preloadAndPlay is a function that loads a series of images then displays them with html5 canvas so it seems like a video/animation. preloadAndPlay是一个函数,该函数加载一系列图像,然后使用html5画布显示它们,因此看起来像是视频/动画。 See above for the preloadAndPlay function that uses promise and recursion. 请参阅上面的有关使用promise和递归的preloadAndPlay函数。 The code works it's just I don't want people to make selection before the video ends. 该代码有效,只是我不希望人们在视频结束之前进行选择。 Above is the code I tried. 上面是我尝试的代码。

There are several issue at code at Question. 在Question的代码中有几个问题。 At preloadImages function the parameter at function passed to Promise constructor is named res , though resolve() is called within function at <img> load event, though resolve is undefined within the function. preloadImages函数中,传递给Promise构造函数的函数参数名为res ,尽管在<img> load事件中在函数中调用了resolve() ,但在函数中未定义resolve handler is not called, not reaching call to undefined resolve() . 未调用handler ,未达到对未定义的resolve()调用。 operate function within Promise constructor is not necessary. Promise构造函数中不需要operate函数。 No value is return ed from operate , see Why is value undefined at .then() chained to Promise? 没有价值return来自ED operate ,请参阅为什么在值。然后()链接到答应未定义? .

You can use Promise.all() to pass an iterable object where chained .then() should be called when all of the values or Promise values passed are fulfilled. 您可以使用Promise.all()来传递,其中链的迭代对象.then()所有这些值,时应该叫Promise传递的值被满足。

Not certain what the expected effect of play() call is, nor is that portion of code mentioned as being a part of the original inquiry. 不确定play()调用的预期效果是什么,也不确定那部分代码是否是原始查询的一部分。 Adjusted code at staccksnippets to call requestAnimationFrame for each image. 调整后的代码片段可以为每个图像调用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