28.01.2018, 17:56
|
Кандидат Javascript-наук
|
|
Регистрация: 11.02.2013
Сообщений: 102
|
|
Помогите оптимизировать код
Всем привет.
есть функция, которая отправляет данные на сервер из локальной Web SQL
function SendPost() {
db.transaction(function (tx) {
tx.executeSql("SELECT keyNumber, itemNumber, curDate FROM items", [], function(tx, results) {
if(results.rows.length > 0) {
for(var i = 0; i < results.rows.length; i++) {
var someArray = [results.rows.item(i).keyNumber,
results.rows.item(i).itemNumber,results.rows.item(i).curDate];
addArray(someArray);
}
}
});
});
function addArray(arr) {
$.ajax({
url: 'http://www.test.ru/add_to_base.php',
dataType: 'text',
type: 'post',
contentType: 'application/x-www-form-urlencoded',
data: ({knb:arr[0], inb:arr[1], cdt:arr[2]}),
success: function( data, textStatus, jQxhr ){
console.log(data);
},
error: function( jqXhr, textStatus, errorThrown ){
if(jqXhr.status&&jqXhr.status==400){
alert("Ошибка!: " + jqXhr.responseText);
}
else if(jqXhr.status&&jqXhr.status==500){
alert("500 - ошибка подключения к серверу");
}
else{
alert("Something went wrong");
}
}
});
}
код работает, но есть вопросы:
1) как лучше оптимизировать, что бы не вызывать каждый раз функцию addArray(). или это нормально - на каждую запись отправлять POST?
2) в случае ошибки, как остановить выполнение кода? например при ошибке 500. Так как цикл уже запустился, то прервать работу SendPost() уже не получается
буду рад любым советам
|
|
28.01.2018, 19:36
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сообщение от Зосимов
|
это нормально - на каждую запись отправлять POST?
|
Лучше сразу все результаты выборки отправить на сервер. Статус 500, это не ошибка подключения.
PS. Ваш код означает, что клиент валит сервер своими запросами, от этого 500. Если каждую запись отправлять отдельно, то делать это нужно только после того, как сервер ответит на предыдущий запрос.
Последний раз редактировалось laimas, 28.01.2018 в 19:55.
|
|
29.01.2018, 07:03
|
Кандидат Javascript-наук
|
|
Регистрация: 11.02.2013
Сообщений: 102
|
|
Сообщение от laimas
|
Лучше сразу все результаты выборки отправить на сервер. Статус 500, это не ошибка подключения.
PS. Ваш код означает, что клиент валит сервер своими запросами, от этого 500. Если каждую запись отправлять отдельно, то делать это нужно только после того, как сервер ответит на предыдущий запрос.
|
так в том то и вопрос - как потравить все результаты?
|
|
29.01.2018, 07:47
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Удалить функцию addArray, перенеся Ajax запрос на место строк 7-11, передавая серверу результат запроса к БД как JSON.
На сервере декодировать и выполнить.
|
|
29.01.2018, 09:08
|
Кандидат Javascript-наук
|
|
Регистрация: 11.02.2013
Сообщений: 102
|
|
Сообщение от laimas
|
передавая серверу результат запроса к БД как JSON.
|
не могли бы привести пример?
|
|
29.01.2018, 09:33
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Не знаю какой пример приводить, так как это связка клиент-сервер. Но коли сервер оперировал одной строкой данных, а теперь получит всю выборку, то серверный скрипт придется все равно править. Поэтому можно отослать как есть, и на сервере оперировать именами полей локальной SQL таблицы - keyNumber, itemNumber, curDate, а не knb, inb, cdt.
В этом случае:
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM items", [], function(tx, results) {
if(results.rows.length > 0) {
$.ajax({
//...
data: 'key='+JSON.stringify(results.rows),
//...
})
}
});
});
На сервере вся выборка, это json_decode($_POST['key']). Если по каким-то причинам этого не желательно, то:
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM items", [], function(tx, results) {
if(results.rows.length > 0) {
for(var i=0, rows=[]; i<results.rows.length; i++) rows.push({
knb:results.rows.item(i).keyNumber,
inb:results.rows.item(i).itemNumber,
cdt:results.rows.item(i).curDate
});
$.ajax({
//...
data: 'key='+JSON.stringify(rows),
//...
})
}
});
});
Многое зависит от операций с данными на сервере.
Последний раз редактировалось laimas, 29.01.2018 в 09:54.
|
|
29.01.2018, 13:39
|
Кандидат Javascript-наук
|
|
Регистрация: 11.02.2013
Сообщений: 102
|
|
laimas, спасибо. буду пробовать.
На сервере строки пишутся в БД в том же виде
|
|
29.01.2018, 13:51
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Если сервер пишет в базу, то тем более выгоднее сразу все вставить, одним запросом многострочной вставкой. А для этого хватит и просто одних значений (без ключей), главное чтобы клиент передавал их в нужном порядке. На сервере эти данные приводятся к запросу:
INSERT INTO tbl (filed, filed, filed) VALUES (val, vall, val), (val, vall, val), (val, vall, val), ... с учетом соглашений и макс. размера пакетной записи.
|
|
29.01.2018, 14:44
|
Кандидат Javascript-наук
|
|
Регистрация: 11.02.2013
Сообщений: 102
|
|
Сообщение от laimas
|
Если сервер пишет в базу, то тем более выгоднее сразу все вставить, одним запросом многострочной вставкой. А для этого хватит и просто одних значений (без ключей), главное чтобы клиент передавал их в нужном порядке. На сервере эти данные приводятся к запросу:
INSERT INTO tbl (filed, filed, filed) VALUES (val, vall, val), (val, vall, val), (val, vall, val), ... с учетом соглашений и макс. размера пакетной записи.
|
примерно так записывал когда приходила строка данных на сервер.
но сейчас на сервер приходит массив такого типа:
(index):349 Array
(
[key] => [{"knb":"111111111111","inb":"222222222222","cdt":"2018-01-29 17:20:27"},{"knb":"qqqqqqqqqqqq","inb":"666666666666","cdt":"2018-01-29 17:21:28"},{"knb":"qqqqqqqqqqqq","inb":"777777777777","cdt":"2018-01-29 17:21:28"}]
)
теперь нужно считать строки на сервере и записывать каждую?
|
|
29.01.2018, 15:10
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
NSERT INTO tbl (field_name, field_name, field_name) VALUES (value, value, value) - это вставка в таблицу одной строки. Можно циклом обойти массив, вставляя таким образом отдельно строки. Но выгоднее сделать один запрос вставив сразу несколько строк, если БД это позволяет. Синтаксис запроса тот же самый, только перечислений вставляемых данных будет равно их числу, с указанием их через запятую:
NSERT INTO tbl (field_name, field_name, field_name) VALUES (value, value, value), (value, value, value), ...
Но при такой записи нужно учитывать максимально разрешенный размер пакетной записи. В MySQL по умолчанию он равен 16 МБ. Если данных гарантированно меньше этого объема, то подготавливаем запрос и выполняем его. В противном случае данные разбиваются на несколько запросов для многострочной вставке. Можно узнать разрешенный размер пакетной записи запросом 'SHOW VARIABLES LIKE "max_allowed_packet"'. Запрос вернет размер в байтах.
Из $_POST нужно еще получить данные:
$data = json_decode($_POST['kye'], 1);
А далее данные из массива $data подготовить для запроса учитывая, что данные должны быть обработаны и соответственно представлены (int или string). Если сервер использует оригинальное расширение MySQL, то придется все делать ручками. В случае если mysqli или PDO, то используя подстановки для подготовленного запроса, а "безопасность" запроса обеспечит сам SQL драйвер.
|
|
|
|