функция продолжает возвращать неопределенный массив, используя Async Await - PullRequest
0 голосов
/ 24 ноября 2018

Не могу заставить мою функцию getJSON вернуть массив.Я пытался использовать await / async, но я делаю что-то не так.

.map и .filter должны быть синхронными, но я также пытался поставить на них await.

$(function() {
    $("#roll").click(async function() {
    var x = await getTreasure()
    chrome.extension.getBackgroundPage().console.log(x)
    });
});

function getTreasure() {
    var sizeValue = $('input[name=size]:checked').val();
    var crValue = $('input[name=challenge]:checked').val();
    var die = Math.floor((Math.random() * 100) + 1);
    var url = "";

    if (sizeValue == "individual") {
        url = chrome.runtime.getURL("treasure_individual.json");
    } else {
        url = chrome.runtime.getURL("treasure_horde.json");
    };
    $.getJSON(url, function(data) {
        var match = data.treasure.filter(function (e) {
            return e.cr == crValue;
        });
        for (i in match[0].roll) {
            var str = match[0].roll[i].d100;
            var arr = str.match(/([0-9]+)/g);
            var levels = $.map(arr, function (x) { 
                return parseInt(x, 10); 
            });

            if (die == levels[0] || die >= levels[0] && die <= levels[1]) {
                chrome.extension.getBackgroundPage().console.log(levels);
                return levels;
            } else {
                return die;
            };
        };
    });
};

Редактировать: Хорошо, не понял, await все еще нужен Promise.Но я все еще не понимаю.Попытался добавить возврат Promise вокруг функции getJson, но она все еще не возвращает levels.

function getTreasure() {
    var sizeValue = $('input[name=size]:checked').val();
    var crValue = $('input[name=challenge]:checked').val();
    var die = Math.floor((Math.random() * 100) + 1);
    var url = "";

    if (sizeValue == "individual") {
        url = chrome.runtime.getURL("treasure_individual.json");
    } else {
        url = chrome.runtime.getURL("treasure_horde.json");
    };

    return new Promise(resolve => {
    $.getJSON(url, function(data) {
        var match = data.treasure.filter(function (e) {
            return e.cr == crValue;
        });
        for (i in match[0].roll) {
            var str = match[0].roll[i].d100;
            var arr = str.match(/([0-9]+)/g);
            var levels = $.map(arr, function (x) { 
                return parseInt(x, 10); 
            });

            if (die == levels[0] || die >= levels[0] && die <= levels[1]) {
                //chrome.extension.getBackgroundPage().console.log(levels);
                return levels;
            };
            };
        });
    });
};

1 Ответ

0 голосов
/ 25 ноября 2018

Способ возврата обещания заключается не в добавлении new Promise (который в данном случае является анти-паттерном), а в получении обещания, которое jQuery уже имеет для вас:

    return $.getJSON(url, function(data) {
//  ^^^^^^
       // .......
    }).promise();
//    ^^^^^^^^^^

NB: во второй попытке вы никогда не звонили resolve.

Если вам нужны "конкретные данные", чтобы быть "обещанными", тогда используйте then вместо использования обратного вызова $.getJSON.Как это:

    return $.getJSON(url).then(function(data) {
//  ^^^^^^               ^^^^^^
       // .......
       return levels;
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...