Задерка между итерациями

30 июля 2008

Не знаю, насколько это очевидно, но sleep можно поместить в условие окончания цикла: эта функция всегда возвращает 0 либо FALSE, а, как известно, x||0 == x

do {
  $result = mysql_query('...');
  $task = mysql_fetch_assoc($result);
  mysql_free_result($result);
} while (!($task || sleep(1)));

Так-то!
UPD: спасибо Alex за исправление.



Пять комментариев. Напиши еще один
  1. C0f8cf83514b22072541680b136ebd25 # 30 июля 2008 Алексей Токарь (blog.azazel.org.ua) написал:

    Данный подход имеет как минимум две проблемы.
    первая – при беглом просмотре кода, не всегда удастся заметить этот sleep
    вторая – сама неочевидность данного решения. Человек не знающий о возвращаемом значении этого sleep будет долго разбираться что же это тут такое происходит

    А ведь хорошим тоном считается писать код для людей а не для машин :)

  2. 77155c3952294adc6d15847fdb26b040 # 30 июля 2008 Alex написал:

    } while (!$task || sleep(1));
    - чето тут перемудрили. Такой цикл сработает с единственной задержкой после последней итерации (которая вероятно тоже будет единственной из-за !$task). ПХП ж не расчитывает второй аргумент ИЛИ если первый дал 1.
    ИМХО правильнее было бы так:
    } while (sleep(1) || $task);

  3. 777894ea5153122bfa6b83f5bbf23622 # 30 июля 2008 Леонид Шевцов (автор) написал:

    Нет-нет, do-while выполняется, пока условие истинно, так что именно !$task.

    А насчет второго замечания вы правы. Только еще правильнее будет
    } while (!$task && !sleep(1))
    или, по правилу де Моргано
    } while (!($task || sleep(1))

    Спасибо, обновил пост.

  4. 77155c3952294adc6d15847fdb26b040 # 30 июля 2008 Alex написал:

    Не, ну может конечно я не врубаюсь в семантику цикла из примера, но ИМХО условие для while неправильное :)
    Давай упростим и выбосим sleep из условия. Когда должен продолжаться цикл? Видимо пока mysql_fetch_assoc возвращает в $task не FALSE. Ну так это записывается как:
    } while ($task); // если напишем !$task, то вылетим после первой итерации в случае непустого рекордсета

    Дальше уже подключим sleep:
    } while (sleep(1) || $task); // ну sleep первым чтоб он по принципу вычисления с лева на право участвовал в каждой итерации

    Вообще если цикл есть обработка строк из одного запроса, то надо тело цикла переписать:
    $result = mysql_query(‘…’);
    do {
    $task = mysql_fetch_assoc($result);
    } while (sleep(1) || $task);
    mysql_free_result($result);

  5. 777894ea5153122bfa6b83f5bbf23622 # 31 июля 2008 Леонид Шевцов (автор) написал:

    Все правильно, но цикл do-while значит «выполнять, пока» – в данном случае «выполнять, пока нет задачи».

    А sleep должен стоять вторым параметром, чтоб при последней итерации он не отрабатывал – зачем спать, если уже выполнено условие выхода из цикла?

    Одним запросом дело не обходится, ибо вся соль в том, что в задачи в базу заносит другой скрипт.

(нужна разметка?)

  • **жирный**
  • > цитата

отменить