嵌套的Javascript异步函数

时间:2017-06-21 18:03:56

标签: javascript arrays function asynchronous

我正在写一个Hearthstone包打开模拟器。当我尝试打开多个包时,我遇到了一个问题。当我打开1包时,我得到了5张牌的阵列。当我打开2包时,我得到2个阵列的10张牌。我希望它是1个10卡的阵列。我认为这与异步函数或回调有关,但不知道如何解决这个问题。

var dataPromise;
var allCards;
var set;
var numberOfPacks;
var commons;
var rares;
var epics;
var legendarys;
var card;
var cardRob;
var pack = [];
var collection = [];
var pittyE;
var pittyL;
$(document).ready(function(){
    getCardData()
    .done(function(data){
        allCards = data;    
    });
    $('#submit').click(function(event){
        event.preventDefault();
            filterByQuality();
            openPacks();
            console.log(collection);
        });
});
function getCardData() {
  if(!dataPromise){
    dataPromise = $.ajax({ // Store jQuery promise so that we can return it for subsequent calls ensuring only one AJAX request is made
      url: 'https://omgvamp-hearthstone-v1.p.mashape.com/cards?collectible=1',
      type: 'GET',
      dataType: 'json',
      beforeSend: function(xhr) {
        xhr.setRequestHeader("X-Mashape-Authorization", "mXtnPm3ltOmshc9dQJjtVdKzfnhbp14UZncjsnfzwvp6uLiMwH");
      }
    });
  } 
  return dataPromise;
};
function filterByQuality(){
     set = document.getElementById('sets').value;
     commons = allCards[set].filter(function(common){
        return common.rarity == "Common"});
     rares = allCards[set].filter(function(rare){
        return rare.rarity == "Rare"});
     epics = allCards[set].filter(function(epic){
        return epic.rarity == "Epic"});
     legendarys = allCards[set].filter(function(legendary){
        return legendary.rarity == "Legendary"});

};
function getCard(){
    var x  = Math.floor((Math.random() * 10000) + 1);
    if (x <= 96){
        card = legendarys[Math.floor(Math.random() * (legendarys.length))];
        pittyL = 0;
    }else if (x > 96 && x <= 420){
        card = epics[Math.floor(Math.random() * (epics.length))];
        pittyE = 0;
    }else if (x > 420 && x <= 2167){
        card = rares[Math.floor(Math.random() * (rares.length))];
    }else{
        card = commons[Math.floor(Math.random() * (commons.length))];
    }
    pack.push(card);
};
function getCardRob(){
    var x = Math.floor((Math.random() * 10000) + 1);
    if (x <= 96){
        card = legendarys[Math.floor(Math.random() * (legendarys.length))];
        pittyL = 0;
    }else if (x > 96 && x <= 420){
        card = epics[Math.floor(Math.random() * (epics.length))];
        pittyE = 0;
    }else{
        card = rares[Math.floor(Math.random() * (rares.length))];
    }
    pack.push(card);
};
function getLegendary(){
    card = legendarys[Math.floor(Math.random() * (legendarys.length))];
    pack.push(card);
    pittyL = 0;
};
function getEpic(){
    card = epics[Math.floor(Math.random() * (epics.length))];
    pack.push(card);
    pittyE = 0;
};
function getPack(){
    pittyL ++;
    pittyE ++;
    if (pittyL == 40 && pittyE == 10){
        getLegendary();
        getEpic();
        getCard();
        getCard();
        getCard();
    } else if (pittyL = 40 && pittyE < 10){
        getLegendary();
        getCard();
        getCard();
        getCard();
        getCard();
    } else if (pittyL < 40 && pittyE == 10){
        getEpic();
        getCard();
        getCard();
        getCard();
        getCard();
    } else {
        getCardRob();
        getCard();
        getCard();
        getCard();
        getCard();
    }
    collection.push(pack);
};
function openPacks(){

    numberOfPacks = document.getElementById('nop').value;

    for (var i = 0; i < numberOfPacks; i++){
        getPack();
    }

};

这是html

​<html>
    <body>
        <header>
            <h1>Hearthstone Pack Simulator</h1>
                <form>
                <select name="sets" id="sets">
                    <option value="Classic">Classic</option>
                    <option value="Goblins vs Gnomes">Goblins vs Gnomes</option>
                    <option value="Journey to Un'Goro">Journey to Un'Goro</option>
                    <option value="Mean Streets of Gadgetzan">Mean Streets of Gadgetzan</option>
                        <option value="The Grand Tournament">The Grand Tournament</option>
                        <option value="Whispers of the Old Gods">Whispers of the Old Gods</option>
                </select>
                    <select name="no of packs" id="nop">
                        <option value="1">1</option>
                        <option value="2">2</option>
                        <option value="20">20</option>
                        <option value="50">50</option>
                        <option value="100">100</option>
                    </select>
                <input type="submit" id="submit">
                </form>
        </header>
        <div>
        </div>
    </body>
</html>

3 个答案:

答案 0 :(得分:0)

1)if (pittyL = 40上的拼写错误,应为if (pittyL == 40)

2)我建议你做一个方法来获得你想要的牌数,这样你就可以做getCard(3);获得3张牌并避免多次使用同一功能。

3)至于包装问题,你的包装变量总是一样的,你总是把卡片推到那个变量上,所以如果你打开100包装,包装就会有500张卡片。至于为什么你有两个包,因为你每次打开包时都在做collection.push(pack);,所以你每次都要推送收集相同的包装参考。

答案 1 :(得分:0)

当您致电getCard()(或其任何变体)时,您正在更新全局pack。您最终会为两个包调用getCard() 10次,因此相同的全局pack会更新10张总卡。 collection也是全局的,并且使用相同的pack两次更新。

为了使其正常工作,您应在每次致电pack时创建一个新的getPack()对象。

一般来说,不要使用全局变量来管理这种状态。而是在每次调用getPack()getCollection()等时创建包或集合对象,然后返回。

您只有一个异步函数可以在开始时获取所有卡数据。异步性不会在这里引起任何问题。

function getCard() {
  let card = /* snip */
  return card;
}
function getPack() {
  let pack = [];
  pack.push(getCard());
  /* snip -- add more cards */
  return pack;
}

答案 2 :(得分:0)

每个getPack()调用都需要单独的pack数组。

请您考虑在scope

中为您的乐趣重写

一旦你使用了对象和正确的范围,就应该没问题。

var variable_passed_to_function;
variable_passed_to_function = 'foo';

console.log( variable_from_outside_of_function );

function myFunction( variable_from_outside_of_function ) {
    let variable_for_only_inside_of_function;
    variable_for_only_inside_of_function = 'bar';
    console.log( variable_from_outside_of_function );
    console.log( variable_for_only_inside_of_function );
    variable_from_outside_of_function = 'baz';
    console.log( variable_from_outside_of_function );
    console.log( variable_for_only_inside_of_function );
    return 'this can be also usable';
}

another_variable = myFunction( variable_passed_to_function );

console.log( another_variable );
console.log( variable_passed_to_function );
console.log( variable_for_only_inside_of_function );