getJSON в цикле

Привет у меня есть вопрос, я написал маленький сканер штрих-кода

Приложение работает так.

  1. сначала я получаю количество заказов от всех заказов с getJSON ordercount
  2. Затем я просматриваю каждый заказ, если штрих-код существует или нет с помощью цикла while
  3. Если штрих-код существует, я запускаю другую функцию и помещаю ее в базу данных.if(myshopdata.order.reference==barcode)

Теперь я хочу запустить функцию no_code() если код не совпадает с циклом while и geJSON завершается в функции get_shop_data

Каждый раз, когда я использую функцию, я получаю сообщение об ошибке до того, как закончим getJson. Но я хочу только сообщение об ошибке, если код не совпадает.

Может ли кто-нибудь помочь мне с моим кодом, как я могу сделать это в моем случае?

В моей программе я вызываю первую функцию с get_order_count(barcode);

function get_order_count(barcode) {
  //Get numbers of Orders
  $.getJSON("http://www.testurl.de/api/orders/?ws_key=TEEUQWTTU1J76LFQE&output_format=JSON", function(data) {
    // JSON Stringify;                          
    var order = JSON.stringify(data);
    var orderdata = JSON.parse(order);
    var ordercount = Object.keys(orderdata.orders).length
    get_shop_data(ordercount, barcode);
  }); //end of get json    
} //end of function

function get_shop_data(ordercount, barcode) {
  var orders = ordercount;
  var i = 1;
  while (i <= orders) {
    //Get Order Data
    $.getJSON("http://www.testurl.de/api/orders/" + i + "?ws_key=TEEUQWTTUJ76LFQE&output_format=JSON", function(data) {
      // JSON Stringify;
      var shopdata = JSON.stringify(data);
      //JSON PHARSE into Object                  
      var myshopdata = JSON.parse(shopdata);
      if (myshopdata.order.reference == barcode) {
        addcode(
          myshopdata.order.reference,
          myshopdata.order.associations.order_rows[0].product_name,
          myshopdata.order.total_paid_tax_incl,
          myshopdata.order.associations.order_rows[0].product_id
        );
        //vibrate if valid   
        navigator.notification.vibrate(4000);
      }
    }); //end of get json
    i++
  } //end of while
  no_code();
} //end of function

function no_code() {
  sweetAlert("code invalid", "Sorry", "error");
}

1 ответ

Проблема в том, что вы пишете синхронный код, но решение требует асинхронного мышления.

В чистом Javascript.

Вот пример того, что вы испытываете. no_code выполняется до получения каких-либо данных из ваших запросов.

function display(id, text) {
  document.getElementById(id).appendChild(document.createTextNode(text + '\n'));
}

function reply(fn, data) {
  setTimeout(function() {
    fn(data);
  }, 2000);
}

function getJSON(url, fn) {
  if (url === 'orders') {
    reply(fn, {
      orders: [1, 2]
    });
  } else if (url === 'order1') {
    reply(fn, {
      order: {
        reference: 123
      }
    });
  } else if (url === 'order2') {
    reply(fn, {
      order: {
        reference: 789
      }
    });
  }
}

function no_code() {
  alert("error");
}

function get_shop_data(ordercount, barcode) {
  var i = 1;
  while (i <= ordercount) {
    getJSON("order" + i, function(data) {
      display('got', JSON.stringify(data));
      if (data.order.reference === barcode) {
        display('match', JSON.stringify(data));
      }
    });
    i += 1;
  }
  no_code();
}

function get_order_count(barcode) {
  getJSON("orders", function(data) {
    var ordercount = Object.keys(data.orders).length;
    get_shop_data(ordercount, barcode);
  });
}

get_order_count(789);
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.0/es6-shim.js"></script>

<fieldset>
  <legend>Received</legend>
  <pre id="got"></pre>
</fieldset>
<fieldset>
  <legend>Matched</legend>
  <pre id="match"></pre>
</fieldset>

Сообщение об ошибке перед тем, как вы получите ответ от getJSON звонки. Решение заключается в использовании Promise s, согласно моим комментариям.

Вот тот же код, но теперь с обещаниями.

function display(id, text) {
  document.getElementById(id).appendChild(document.createTextNode(text + '\n'));
}

function reply(fn, data) {
  setTimeout(function() {
    fn(data);
  }, 2000);
}

function getJSON(url, fn) {
  if (url === 'orders') {
    reply(fn, {
      orders: [1, 2]
    });
  } else if (url === 'order1') {
    reply(fn, {
      order: {
        reference: 123
      }
    });
  } else if (url === 'order2') {
    reply(fn, {
      order: {
        reference: 789
      }
    });
  }
}

function no_code() {
  alert("error");
}

function get_shop_data(ordercount, barcode) {
  var requests = []
  var i = 1;
  while (i <= ordercount) {
    var p = new Promise(function(resolve, reject) {
      getJSON("order" + i, function(data) {
        display('got', JSON.stringify(data));
        if (data.order.reference === barcode) {
          display('match', JSON.stringify(data));
        }
        resolve('success');
      });
    });
    requests.push(p);
    i += 1;
  }
  Promise.all(requests).then(no_code);
}

function get_order_count(barcode) {
  getJSON("orders", function(data) {
    var ordercount = Object.keys(data.orders).length;
    get_shop_data(ordercount, barcode);
  });
}

get_order_count(789);
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.0/es6-shim.js"></script>

<fieldset>
  <legend>Received</legend>
  <pre id="got"></pre>
</fieldset>
<fieldset>
  <legend>Matched</legend>
  <pre id="match"></pre>
</fieldset>

Сейчас no_code выполняется после того, как запросы были разрешены.

Вы хотите использовать jQuery, поэтому вам нужно будет прочитать их документацию и использовать их API, но принцип тот же.

Другие вопросы по тегам