Задерка между итерациями 30 июля 08

Не знаю, насколько это очевидно, но 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 за исправление.

Комментарии

  • Алексей Токарь 30 июля 2008

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

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

  • Alex 30 июля 2008

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

  • coldFlame 30 июля 2008

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

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

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

  • Alex 30 июля 2008

    Не, ну может конечно я не врубаюсь в семантику цикла из примера, но ИМХО условие для 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);

  • coldFlame 31 июля 2008

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

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

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

Оставить комментарий

  • (или OpenID)
  •