如何让它等到一切都结束,直到下一次迭代

时间:2016-11-13 23:57:19

标签: javascript jquery asynchronous synchronization settimeout

所以我在这里有这个功能,我用来迭代音节,这是对象的数组

function showImagesByPairAtInterval(Syllables, interval, index) {
            index = index || 0;
            let slice = Syllables[index];
            nextIndex = index + 1;
            drawimagesonCanvas(slice.Url1, slice.Url2);//not finishing

            if (nextIndex <= Syllables.length - 1) {
                syllable_text.html(slice.The_Syl);

                setTimeout(showImagesByPairAtInterval.bind(
                    null,
                    Syllables,
                    interval,
                    nextIndex
                ), interval);
            }
            else {
                explain.html("Try Me Again");
                syllable_text.html("<br/>");
                $('#translate_button').removeAttr('disabled');
            }
        }

问题是drawimagesonCanvas无法完成其工作,并且在interval时间之后进入下一次迭代

以下是drawimagesonCanvas代码:

 function drawimagesonCanvas(url1,url2)
    {
        var canvas = document.getElementById("canvas_images");

        var IsBoth = (url2=="null");
        var context = canvas.getContext('2d');

        var img1 = new Image();
        var img2 = new Image();
        context.clearRect(0, 0, canvas.width, canvas.height);


        if (!IsBoth) {
                img1.onload = function () {
                    context.drawImage(img1, 0, 0, 150, 350);

                };
                img1.src = api + url1;

                img2.onload = function () {
                    context.drawImage(img2, 150, 0, 150, 350);
                };
                img2.src = api + url2;
        }
        else
        {
            img1.onload=function(){

            context.drawImage(img1,0,0,300,350);
            }
            img1.src = api + url1;

        }

有没有办法让这个问题消失,请注意图像是在服务器上在线并且它不是本地的

1 个答案:

答案 0 :(得分:1)

你可以向drawimagesonCanvas添加一个回调,但是当你可能正在等待一两张图像时,这会使用回调变得复杂,而不是不可能,只是(在我看来)凌乱

使用Promise是一个更清洁的解决方案。

首先,我创建了一个函数loadImage,它返回一个在加载图像后解析的Promise。通过这种方式,我可以在有两张图片时使用Promise.all,只需返回loadImage的承诺,只有一张

注意,我还将IsBoth的逻辑更改为更正&#34;正确&#34;,即当要加载两个图像时IsBoth为TRUE。

drawimagesonCanvas返回一个Promise,一旦图像完成就会解析,然后检查是否需要进行更多处理,并像在代码中一样使用setTimeout调用drawimagesonCanvas

function drawimagesonCanvas(url1, url2) {
    var canvas = document.getElementById("canvas_images");
    var IsBoth = (url2 != "null");
    var context = canvas.getContext('2d');
    let loadImage = (url, x, y, w, h) => new Promise((resolve, reject) => {
        var img = new Image();
        img.addEventListener('load', () => {
            context.drawImage(img, x, y, w, h);
            resolve();
        });
        img.src = url;
    });
    context.clearRect(0, 0, canvas.width, canvas.height);
    if (IsBoth) {
        return Promise.all([
            loadImage(api + url1, 0, 0, 150, 350),
            loadImage(api + url2, 150, 0, 150, 350)
        ]);
    } else {
        return loadImage(api + url1, 0, 0, 300, 350);
    }
}

function showImagesByPairAtInterval(Syllables, interval, index) {
    index = index || 0;
    let slice = Syllables[index];
    nextIndex = index + 1;
    drawimagesonCanvas(slice.Url1, slice.Url2)
    .then(() => {
        if (nextIndex <= Syllables.length - 1) {
            syllable_text.html(slice.The_Syl);
            setTimeout(showImagesByPairAtInterval.bind(
                null,
                Syllables,
                interval,
                nextIndex
            ), interval);
        } else {
            explain.html("Try Me Again");
            syllable_text.html("<br/>");
            $('#translate_button').removeAttr('disabled');
        }
    });
}