#javascript #jquery #arrays #couchdb
#javascript #jquery #массивы #couchdb
Вопрос:
Это код (см. КОД) Я использую, когда пытаюсь создать новый документ CouchDB. Документ содержит один или несколько существующих документов CouchDB (отслеживание истории). Результирующий json (см. JSON) для вновь созданного документа выглядит примерно так:
JSON:
{
"_id": "b3360050039389801524044daf1c963c",
"_rev": "1-2a5da40ce9a191b4decc27411ec9a181",
"hodoc_type": "INCOMMING DELIVERY NOTE",
"user_from": "ANS USER",
"status": "INSTALLED ON SITE",
"category": "ASET",
"location": "MTX SPARE",
"doctype": "hodoc",
"items": [
{
"serial_number": "310310007590",
"status": "STORED IN WAREHOUSE",
"doctype": "data",
"supplier": "INTRACOM",
"po": "0",
"category": "SPARE PART",
"user_out": "IGOR JURUKOV",
"mac": "NULL",
"eqtype": "IDU",
"location": "MTX SPARE",
"location_comment": "NULL",
"date_in": "2011-05-06",
"date_out": "2011-05-06",
"prf": "0",
"part_number": "Z00-404/63.01",
"user_in": "KOTE JANAKIEVSKI",
"bar_code": "0",
"manufacturer": "INTRACOM",
"rma": "NULL",
"product_name": "PSU for IDR-SM"
},
{
"serial_number": "310407016955",
"status": "STORED IN WAREHOUSE",
"doctype": "data",
"supplier": "INTRACOM",
"po": "0",
"category": "SPARE PART",
"user_out": "IGOR JURUKOV",
"mac": "NULL",
"eqtype": "IDU",
"location": "MTX SPARE",
"location_comment": "NULL",
"date_in": "2011-05-06",
"date_out": "2011-05-06",
"prf": "0",
"part_number": "Z00-404/63.02",
"user_in": "KOTE JANAKIEVSKI",
"bar_code": "0",
"manufacturer": "INTRACOM",
"rma": "NULL",
"product_name": "PSU for IDR-SM"
}
]
}
код:
var docids = new Array();
var items = new Array();
$('div#divitemsout').find('img.item-out-remove').each(function () {
var id = $(this).attr('attrid');
if (docids.indexOf(id) == -1) {
docids.push(docid);
}
var item = new Object;
$.getJSON('/whdb/' id, function(data) {
$.each(data, function(key, val) {
if (key !== "_id" amp;amp; key !== "_rev") {
item[key] = val;
}
});
// Check No.1
//alert(item.manufacturer);
});
// Check No.2
//alert(item.manufacturer);
items.push(item);
});
Проблема и вопрос заключаются в следующем: когда выполняется приведенная ниже проверка строки №2, частью «items» результирующего документа json является [] . Когда приведенная ниже проверка № 2 предупреждения (item.manufacturer) не прокомментирована, я получаю предупреждения с содержимым «undefined», но часть «items» результирующего документа json установлена правильно, как показано в примере. Есть предложения?
Ответ №1:
Проблема просто во времени. Функция, которую вы передаете getJSON
, не вызывается до тех пор, пока веб-сервер не вернет ответ на ваш запрос. So item
не будет определено сразу после вызова getJSON
. Добавление alert
вызовов просто замедляет работу, так что у асинхронного вызова есть время для завершения.
Попробуйте переместить items.push(item)
строку внутри getJSON
обратного вызова.
Редактировать
Чтобы внести ясность, попробуйте это (в Chrome или Firefox с открытым Firebug, чтобы у вас была правильная console.log
функция):
var docids = new Array();
var items = new Array();
var waiting = 0;
$('div#divitemsout').find('img.item-out-remove').each(function () {
var id = $(this).attr('attrid');
if (docids.indexOf(id) == -1) {
docids.push(docid);
}
var item = new Object;
waiting ;
$.getJSON('/whdb/' id, function(data) {
waiting--;
$.each(data, function(key, val) {
if (key !== "_id" amp;amp; key !== "_rev") {
item[key] = val;
}
});
items.push(item);
if(waiting == 0) {
console.log('items:', items);
}
});
});
Комментарии:
1. Извините, Джорджджи, я вам не верю. Вы ждете, пока ваши
getJSON
методы обратного вызова сработают, прежде чем записывать содержимое вашегоitems
массива?2. Я не понимаю вопроса, но есть одна вещь, которую я должен сказать. Если я раскомментирую предупреждение при проверке № 1, я получу правильное значение для item.manufacturer, и items заполняется не так, как хотелось бы, независимо от того, находится оно внутри или вне кода getJSON. Если я раскомментирую предупреждение при проверке № 2, я получу «undefined» для item.manufacturer, и items в порядке, независимо от того, находится оно внутри или вне кода getJSON. Я попытался вызвать $.ajax(url, { async: false, … } с тем же успешным результатом.
3. @Gjorgji — вы должны получать ‘undefined’ для,
item.manufacturer
покаgetJSON
метод не будет запущен, что происходит после кода, который вы поставили на «Check No. 2» — то есть, как я уже упоминал, просто по времени. У вас есть две вещи, называемые «элементами» — переменная в коде и поле в документе JSON. Какой из них, вы имеете в виду, иногда является правильным? Откуда вы знаете — например, используете ли вы что-то вродеconsole.log("items: ", items)
? Можете ли вы показать свой метод проверки «элементов»?4. элементы — это массив. Каждый элемент в массиве является объектом (item). Я проверяю выполнение кода с помощью оповещения (item.manufacturer). Проверка также может быть выполнена через item.product_name, item.serial_number и т.д. Я также использовал $(‘div#somedivid’).append(item.manufacturer ‘<br>’); но результаты были теми же.
5. @Gjorgji: Я отредактировал свой ответ, чтобы показать, как дождаться возврата всех асинхронных вызовов ajax, прежде чем печатать значение массива items.