Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP Puzzles. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Ajax
 
 автор: Lelik   (20.08.2009 в 19:56)   письмо автору
 
 

Вот такая ситуация: я послал на сервер 2 запроса (кликнул на одной кнопке скоторой вызывается функция, потом на другой). Ответ на второй запрос приходит от сервера раньше первого, соответсвенно функция которая должна быть при ответе с сервера для первого запроса перетирается (другими словами, после полученя ответа на первый запрос, назначенная на этот ответ функция не исполняется).
Как можно избежать подобного, что бы все функции выполнялись после получения ответа?

  Ответить  
 
 автор: Евгений Петров   (21.08.2009 в 00:29)   письмо автору
 
   для: Lelik   (20.08.2009 в 19:56)
 

Аякс запросы можно делать в синхронном режиме. Тогда у вас просто не получится кнопку вторую нажать. Но вообще сама ситуация неправильная. Ф-ии должны корректно работать независимо от того какой ответ пришел быстрее. Вы можете при вызове каждой из ф-й передавать управление 3-й ф-ии, которая будет анализировать текущее состояние и либо ничего не делать (если ответ пришел от одного сервера) либо делать что то (если все ответы пришли).. Надо на конкретную ситуацию смотреть. Что там у вас?

  Ответить  
 
 автор: Lelik   (21.08.2009 в 00:53)   письмо автору
3.7 Кб
 
   для: Евгений Петров   (21.08.2009 в 00:29)
 

файл 1

<?php
header
("Content-Type: text/html;charset=utf-8");
?>
<html>
    <head>
        <script type="text/javascript" src="common.js"></script>
        <script type="text/javascript" src="ajax.js"></script>
        <script>
        function Function1() {
            var load = new _AJAX.LoadXMLDoc('ajax.php?req_1=1', 'get', Function1_, false);
        }
        function Function1_(oData) {
            me('block_1').innerHTML = oData.responseText;
        }
        function Function2() {
            var load = new _AJAX.LoadXMLDoc('ajax.php?req_2=1', 'get', Function2_, false);
        }
        function Function2_(oData) {
            me('block_2').innerHTML = oData.responseText;
        }
        </script>
    </head>
    <body>
        <span onclick="Function1()">Вызвать функцию Function1();</span>
        <div id="block_1">0</div>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <span onclick="Function2()">Вызвать функцию Function2();</span>
        <div id="block_2">0</div>
    </body>
</html>


файл 2

<?php
if( isset($_REQUEST['req_1']) && $_REQUEST['req_1'] != '' ) {
    for(
$i=0$i<99999999$i++) {
        
$j=0;
    }
    
    print 
'1) '.$i;
}
if( isset(
$_REQUEST['req_2']) && $_REQUEST['req_2'] != '' ) {
    for(
$i=0$i<100$i++) {
        
$j=0;
    }
    
    print 
'2) '.$i;
}
?>

  Ответить  
 
 автор: Евгений Петров   (22.08.2009 в 00:42)   письмо автору
 
   для: Lelik   (21.08.2009 в 00:53)
 

Хотелось бы ещё посмотреть на файлы common.js и ajax.js

  Ответить  
 
 автор: Lelik   (22.08.2009 в 02:38)   письмо автору
 
   для: Евгений Петров   (22.08.2009 в 00:42)
 

Аякс.жс в аттаче к предыдущему моему посту

  Ответить  
 
 автор: dyadya   (22.08.2009 в 10:22)   письмо автору
 
   для: Lelik   (22.08.2009 в 02:38)
 

На common.js тоже хотелось бы глянуть...

Если уж Вы вызываете две разных функции, назначьте, не мудрствуя лукаво, для каждой свой обработчик...

  Ответить  
 
 автор: Lelik   (22.08.2009 в 22:15)   письмо автору
 
   для: dyadya   (22.08.2009 в 10:22)
 

common.js здесь не играет никакой роли. оттуда берутся функции для проверки браузера (ИЕ это или не ИЕ).

  Ответить  
 
 автор: dyadya   (23.08.2009 в 07:01)   письмо автору
 
   для: Lelik   (22.08.2009 в 22:15)
 

Тогда откуда me('block_2')?

  Ответить  
 
 автор: Lelik   (23.08.2009 в 14:21)   письмо автору
 
   для: dyadya   (23.08.2009 в 07:01)
 

ну это к делу отношения не имеет.

  Ответить  
 
 автор: Евгений Петров   (23.08.2009 в 17:28)   письмо автору
 
   для: Lelik   (22.08.2009 в 02:38)
 

А, да, извиняюсь, не заметил.
Насколько мне подсказывает моя интуиция проблемма в том что вы храните данные о состоянии обьекта глобально.
Например:
_AJAX.XMLReqFunction = sFunction;

_AJAX существует в одном экземпляре и этим присваиванием вы просто перетираете калбэк.
Я бы вам посоветовал использовать готовые библиотеки для работы с аяксом. Их полно на любой цвет и вкус.
Сам лично люблю JQuery.

  Ответить  
 
 автор: Lelik   (23.08.2009 в 17:50)   письмо автору
 
   для: Евгений Петров   (23.08.2009 в 17:28)
 

cпасибо, за советы, но сторонние библиотеки юзать желания нету :)

  Ответить  
 
 автор: Евгений Петров   (23.08.2009 в 18:21)   письмо автору
 
   для: Lelik   (23.08.2009 в 17:50)
 

Почему, думаете вы лучше сможете сделать? )

  Ответить  
 
 автор: Lelik   (23.08.2009 в 19:26)   письмо автору
 
   для: Евгений Петров   (23.08.2009 в 18:21)
 

да. думаю да. потом, по лишнему весу и скорости исполнения - это не самое лучшее решение.

  Ответить  
 
 автор: Евгений Петров   (23.08.2009 в 21:42)   письмо автору
 
   для: Lelik   (23.08.2009 в 19:26)
 

тот же JQuery в сжатом виде весит 19 кб. Ваш код может получиться меньшим в обьеме но по функционалу JQuery Вам не обогнать. Кроме того по скорости он ни чуть не меньше чем это впринципе возможно.
Я всеми руками за методику обучения: "пока сам не попробуешь не поймешь", но когда дело доходит до конкретных задач писать что то свое зачастую нет смысла.
Я не придумываю свой язык на котором лично мне будет удобно писать. Я пользуюсь уже существующими языками, разработкой которых занимаеться не один человек а группа, у которых за плечами большой опыт и знания в этой области. Это так же касается и других вещей.
JQuery это не просто библиотека для AJAX - это полноценный кроссбраузерный яваскрипт-фреймворк. Он вам и Ваши "me" заменит и ещё много чего.

  Ответить  
 
 автор: Lelik   (24.08.2009 в 01:36)   письмо автору
 
   для: Евгений Петров   (23.08.2009 в 21:42)
 

Кроме того по скорости он ни чуть не меньше чем это впринципе возможно.
:)

но когда дело доходит до конкретных задач писать что то свое зачастую нет смысла.
:)

  Ответить  
 
 автор: Евгений Петров   (24.08.2009 в 13:26)   письмо автору
 
   для: Lelik   (24.08.2009 в 01:36)
 

Многозначительно...

  Ответить  
 
 автор: Trianon   (24.08.2009 в 13:36)   письмо автору
 
   для: Евгений Петров   (24.08.2009 в 13:26)
 

ну ведь чушь же написали.. и теперь удивляетесь.

  Ответить  
 
 автор: Евгений Петров   (24.08.2009 в 13:42)   письмо автору
 
   для: Trianon   (24.08.2009 в 13:36)
 

Ну раз уж начали - переубедите, чем в данном случае писать свое лучше чем использовать готовое?

  Ответить  
 
 автор: Trianon   (24.08.2009 в 14:24)   письмо автору
 
   для: Евгений Петров   (24.08.2009 в 13:42)
 

зачем?

  Ответить  
 
 автор: Евгений Петров   (24.08.2009 в 14:33)   письмо автору
 
   для: Trianon   (24.08.2009 в 14:24)
 

А зачем писать мне что я говорю чушь?

  Ответить  
 
 автор: Lelik   (24.08.2009 в 14:45)   письмо автору
 
   для: Евгений Петров   (24.08.2009 в 14:33)
 

ну потому что ты не ознакомившись подробно с вопросом вещаешь полную чушь. а потом просишь переубедить. :)

  Ответить  
 
 автор: Евгений Петров   (24.08.2009 в 14:50)   письмо автору
 
   для: Lelik   (24.08.2009 в 14:45)
 

Ну вот опять. Если я говорю что человек говорит чушь то я цитирую его и привожу доводы почему он говорит чушь. Вы же в качестве доводов пишете только смайлики. Я по всей видимости ещё не настолько крут чтобы понимать вас с полуслова.
За все что я написал я могу ответить. А вы можете?

  Ответить  
 
 автор: dyadya   (24.08.2009 в 00:54)   письмо автору
 
   для: Lelik   (22.08.2009 в 02:38)
 

Вы создаете XMLHttpRequest-объект как свойство глобального объекта _AJAX.

_AJAX.Answer = new _AJAX.Req()]


Но, чтобы обрабатывать одновременно несколько XMLHttpRequest-запросов, необходимо для каждого из них создавать свой XMLHttpRequest-объект. Можно либо поместить их в массив, либо (что, намного удобнее) создавать XMLHttpRequest-объект внутри вызывающей функции с
помощью анонимной...

P.S. Не совсем понятно назначение этого кусочка кода:

if(_AJAX.Answer.responseText != '') {
                new _AJAX.XMLReqFunction(_AJAX.Answer);
            }
            else {
                new _AJAX.XMLReqFunction(_AJAX.Answer);
            }

  Ответить  
 
 автор: Lelik   (24.08.2009 в 01:41)   письмо автору
 
   для: dyadya   (24.08.2009 в 00:54)
 

дело как раз не вот в этом месте, так как с помощью опереатора new создается экземпляр объекта, а это не ссылка на глобальный объект.

_AJAX.Answer = new _AJAX.Req()


Можно либо поместить их в массив
да уже делаю так, но хочу без них как-то обойтись.


ЗЫ. когда-то эта библиотека принимала код в виде {'name':'value'}, и на приеме ответа стоял обработчик.

  Ответить  
 
 автор: dyadya   (24.08.2009 в 12:20)   письмо автору
 
   для: Lelik   (24.08.2009 в 01:41)
 

дело как раз не вот в этом месте, так как с помощью опереатора new создается экземпляр объекта, а это не ссылка на глобальный объект.


Вы делаете два запроса, создаете два объекта new _AJAX.Req() и к каждому обращаетесь через _AJAX.Answer?

  Ответить  
 
 автор: dyadya   (24.08.2009 в 12:53)   письмо автору
 
   для: Lelik   (24.08.2009 в 01:41)
 

Похоже собака зарыта здесь:

var load = new _AJAX.LoadXMLDoc('ajax.php?req_1=1', 'get', Function1_, false);


Надо, наверное сделать:
load = new _AJAX

а дальше уже:
load.LoadXMLDoc('ajax.php?req_1=1', 'get', Function1_, false);

  Ответить  
 
 автор: Евгений Петров   (24.08.2009 в 13:40)   письмо автору
 
   для: Lelik   (24.08.2009 в 01:41)
 

И все таки дело как раз и в этом месте и во многих других. Да вы создаете оператором new новый экземпляр обьекта, но это экземпляр _AJAX.Req а не _AJAX. _AJAX.Answer существует в единственном экземпляре и вы его замечательно перетираете.

  Ответить  
 
 автор: Lelik   (24.08.2009 в 15:32)   письмо автору
 
   для: Евгений Петров   (24.08.2009 в 13:40)
 

в общем, убрал всё глобальное, и всё равно работает не так как мне надо

_AJAX = function( sUrl, sMethod, sFunction, sParams ) {
    /*
    sUrl - url на который посылается запрос
    sMethod - метод get или post
    sFunction - функция-обработчик выполняемая в слычае ответа 200 сервера
    sParams - параметры, необходимо для post запросов
    */
    /* Посылка запроса на сервер */
    sMethod = (typeof sMethod == 'undefined') ? 'GET' : sMethod;
    sFunction = (typeof sFunction == 'undefined') ? false : sFunction;
    sParams = (typeof sParams == 'undefined') ? ( ( _MC.isIe() ) ? '' : null ) : sParams;
    
    _this = this;
    this.oLoad = XMLHttpRequest() ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    
    if (this.oLoad) {
        this.oLoad.open(sMethod, sUrl, true);
        if (sMethod.toLowerCase() == 'post') {
            this.oLoad.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            this.oLoad.setRequestHeader("Content-length", sParams.length);
            this.oLoad.setRequestHeader("Connection", "close");
        }
        this.oLoad.setRequestHeader("X-Requested-With", "XMLHttpRequest");
        if (sFunction) {
            this.AnswerFunc = sFunction;
            this.ReqTimer = null
            this.oReqState = function() {
                /* Получаем состояние готовности сервера выдать ответ */
                if(_this.ReqTimer != null) {
                    clearTimeout(_this.ReqTimer);
                }
                
                if(_this.oLoad.readyState == 4) {
                    if (_this.oLoad.status == 200) {
                        _this.AnswerFunc(_this.oLoad);
                    }
                    clearTimeout(_this.ReqTimer);
                    _this.ReqTimer = null;
                }
                else {
                    _this.ReqTimer = setTimeout(_this.oReqState, 10);
                }
            }
            this.oReqState();
        }
        this.oLoad.send( unescape(sParams) );
    }
    else
        return false;
}


ЗЫ. посылаю запросы теперь так:

new _AJAX('ajax.php?req_1=1', 'get', Function1_, false);

  Ответить  
 
 автор: Lelik   (24.08.2009 в 15:36)   письмо автору
 
   для: Lelik   (24.08.2009 в 15:32)
 

заработало :) исправил приведённую мной функцию в одном месте:
var _this = this;

  Ответить  
 
 автор: Евгений Петров   (24.08.2009 в 15:37)   письмо автору
 
   для: Lelik   (24.08.2009 в 15:32)
 

Дайте рабочий пример чтобы можно было запустить.

  Ответить  
 
 автор: Lelik   (24.08.2009 в 15:43)   письмо автору
 
   для: Евгений Петров   (24.08.2009 в 15:37)
 

index.php

<?php
header
("Content-Type: text/html;charset=utf-8");
?>
<html>
    <head>
        <script type="text/javascript" src="common.js"></script>
        <script type="text/javascript" src="ajax.js"></script>
        <script>
        function Function1() {
            new _AJAX('ajax.php?req_1=1', 'get', Function1_, false);
        }
        function Function1_(oData) {
            me('block_1').innerHTML = oData.responseText;
        }
        function Function2() {
            new _AJAX('ajax.php?req_2=1', 'get', Function2_, false);
        }
        function Function2_(oData) {
            me('block_2').innerHTML = oData.responseText;
        }
        </script>
    </head>
    <body>
        <span onclick="Function1()">Вызвать функцию Function1();</span>
        <div id="block_1">0</div>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <br/>
        <span onclick="Function2()">Вызвать функцию Function2();</span>
        <div id="block_2">0</div>
    </body>
</html>


ajax.php

<?php
if( isset($_REQUEST['req_1']) && $_REQUEST['req_1'] != '' ) {
    for(
$i=0$i<99999999$i++) {
        
$j=0;
    }
    
    print 
'1) '.rand(1,500);
}
if( isset(
$_REQUEST['req_2']) && $_REQUEST['req_2'] != '' ) {
    for(
$i=0$i<100$i++) {
        
$j=0;
    }
    
    print 
'2) '.rand(1,500);
}
?>


ajax.js. тут есть одно "но": _MC.isIe() - надо заментить на проверку ИЕ это или нет.

/* © Ильюша Абельчаков. http://www.ilyuha.ru/ */
_AJAX = function( sUrl, sMethod, sFunction, sParams ) {
    /*
    sUrl - url на который посылается запрос
    sMethod - метод get или post
    sFunction - функция-обработчик выполняемая в слычае ответа 200 сервера
    sParams - параметры, необходимо для post запросов
    */
    /* Посылка запроса на сервер */
    sMethod = (typeof sMethod == 'undefined') ? 'GET' : sMethod;
    sFunction = (typeof sFunction == 'undefined') ? false : sFunction;
    sParams = (typeof sParams == 'undefined') ? ( ( _MC.isIe() ) ? '' : null ) : sParams;
    
    var _this = this;
    this.oLoad = XMLHttpRequest() ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    
    if (this.oLoad) {
        this.oLoad.open(sMethod, sUrl, true);
        if (sMethod.toLowerCase() == 'post') {
            this.oLoad.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            this.oLoad.setRequestHeader("Content-length", sParams.length);
            this.oLoad.setRequestHeader("Connection", "close");
        }
        this.oLoad.setRequestHeader("X-Requested-With", "XMLHttpRequest");
        if (sFunction) {
            this.AnswerFunc = sFunction;
            this.ReqTimer = null;
            this.oReqState = function() {
                /* Получаем состояние готовности сервера выдать ответ */
                if(_this.ReqTimer != null) {
                    clearTimeout(_this.ReqTimer);
                }
                
                if(_this.oLoad.readyState == 4) {
                    if (_this.oLoad.status == 200) {
                        _this.AnswerFunc(_this.oLoad);
                    }
                    clearTimeout(_this.ReqTimer);
                    _this.ReqTimer = null;
                }
                else {
                    _this.ReqTimer = setTimeout(_this.oReqState, 10);
                }
            }
            this.oReqState();
        }
        this.oLoad.send( unescape(sParams) );
    }
    else
        return false;
}

  Ответить  
 
 автор: Евгений Петров   (24.08.2009 в 15:48)   письмо автору
 
   для: Lelik   (24.08.2009 в 15:43)
 

Я пример попросил одновременно с тем как вы заставили его работать. Ещё что то не работает?

  Ответить  
 
 автор: Lelik   (24.08.2009 в 15:49)   письмо автору
 
   для: Евгений Петров   (24.08.2009 в 15:48)
 

телевизор ;)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования