Проблемы с асин c и ждут в Javascript - PullRequest
2 голосов
/ 26 апреля 2020

Это мой первый вопрос здесь, и я пытался осмотреться, чтобы посмотреть, не найду ли я что-то, что имеет смысл, но до сих пор я не мог по-настоящему обдумать, как это сделать.

Хорошо, моя проблема в том, что я сейчас создаю скрипт, который будет извлекать изображения (карточек) из API и отображать их на холсте, пока что все это прекрасно работает.

this.drawCard = function() 
{
    img.src = this.card_pic;
    img.onload = () => {
        c.drawImage(img, x, y, crdwid, crdhei); // Draws the card.
    }
}

Проблема, с которой я сталкиваюсь, заключается в том, что я разрешаю пользователю нажимать на изображение, чтобы изменить его на другую версию. Когда они нажимают на изображение, я составляю список других похожих изображений: отправка запроса через API. Иногда это занимает некоторое время и, таким образом, выдает ошибку GET net :: ERR_FILE_NOT_FOUND, хотя и работает, если вы нажмете еще раз. Поэтому я хотел бы подождать, пока код завершит sh создание массива, прежде чем пытаться изменить изображение.

this.grabPics = function()
{
    if(pics.length == 0)
    {
        console.log('Making Array of pics.');
        postData(this.prints).then((data) => { 
            // This .then works fine, and does the job correctly. 
            // It calls a function based on the cache fetched from this tutorial. https://www.sitepoint.com/cache-fetched-ajax-requests/
            for(var i = 0; i < data.total_cards; i++)
            {
                pics.push(data.data[i].image_uris.large);
            }
        });
    }
}

this.nextPic = function()
{
    if (this.reprint)
    {
        this.grabPics(); // I believe I need a await, or .then here.
        this.card_pic = pics[picNum]; // Because this uses the array from grabPics.
        this.drawCard(); // And this draws the next picture.
        picNum++; // Should probably do this earlier.
        if (picNum >= pics.length)
        {
        picNum = 0;
        }
    }
}

Я пробовал несколько методов:

  • У меня есть попытался сделать grabPics asyn c функцией и используя grabPics (). then (... все остальное ...) grabPics (); несколькими способами, используя обещания и тому подобное, даже объявляя пользовательские обещания.

Проблема, с которой я сталкиваюсь, заключается в том, что, когда я делаю эти вещи, я избегаю сообщения об ошибке, которое я получаю, имея код как есть. производит, но это никогда не меняет картину, и, кажется, никогда не выполняет функцию nextPi c снова, даже при повторном нажатии ... что я пропускаю?

Извините, если это глупость вопрос, я просто не могу по-настоящему обернуть голову, куда положить асин c, await или then ().

РЕДАКТИРОВАТЬ: Мои попытки:

Попытка 1:

this.grabPics = async function()
{
    return new Promise(resolve => {
        if(pics.length == 0)
        {
            console.log('Making Array of pics.');
            postData(this.prints).then((data) => {
                for(var i = 0; i < data.total_cards; i++)
                {
                    pics.push(data.data[i].image_uris.large);
                }
                console.log(pics);
                resolve('true');
            });
        }
    });
}

this.nextPic = function() 
{
    if (this.reprint)
    {
        this.grabPics().then(resolve => {
            this.card_pic = pics[picNum];
            this.drawCard();
            picNum++;
            if (picNum >= pics.length)
            {
                picNum = 0;
            }
        });
    }
}

Попытка 2:

this.grabPics = function()
{
    return new Promise(resolve => {
        if(pics.length == 0)
        {
            console.log('Making Array of pics.');
            postData(this.prints).then((data) => {
                for(var i = 0; i < data.total_cards; i++)
                {
                    pics.push(data.data[i].image_uris.large);
                }
                resolve('go');
            });
        }
    }); 
}

this.nextPic = async function() 
{
    if (this.reprint)
    {
        const result = await this.grabPics();
        this.card_pic = pics[picNum];
        this.drawCard();
        picNum++;
        if (picNum >= pics.length)
        {
            picNum = 0;
        }
    }
}

1 Ответ

0 голосов
/ 26 апреля 2020

Хорошо, я думаю, что нашел и решил свою проблему.

Добавление возврата до postData, как указал Алексей, похоже, сработало.

Однако, почему это не сработало, это потому, что возврат был завернут в проверку if(pics.length == 0). Поэтому я добавил еще один с собственным возвратом, который, похоже, позволял nextPi c продолжать повторные нажатия.

...