PDA

Просмотр полной версии : Ожидание завершения функции


DevastT
17.07.2009, 23:15
Вообщем есть такая проблема . Есть программа вида
onMouseDown = function()
{
долговыполняющаяся_функция();
}
И при массовых нажатиях мышки всё естественно виснет. Хотелось блокировать нажатие мышки на время выполнения функции :
block = false;

onMouseDown = function()
{
if ( block == false )
{
block = true;
долговыполняющаяся_функция();
block = false;
}
}

но так не работает...может кто подскажет как это сделать?

silin
17.07.2009, 23:47
попробуй так
var time:Number = getTimer();
function onMouseDown()
{
if (getTimer() - time < 10) return;//10 с потолка
time = getTimer();
test();//долговыполняющаяся_функция;
time = getTimer();
}

DevastT
18.07.2009, 00:08
Спасибо! Тока забыл отписать что время выполнения функции может сильно меняться, так что через таймеры врят ли прокатит. Может события как-то можно для этого использовать?

silin
18.07.2009, 00:14
onMouseDown и есть событие, только проблема в том, что выстреливает оно не во время реального клика, а после завершения потока обработки в этой самой функции, поэтому и установка флага не срабатывает
а с отсечкой по getTimer хоть что-то похожее на правду..

DevastT
18.07.2009, 00:27
блин...не айс получается...просто предполагается запуск этой функции на машинах разной производительности, и получается надо её сначала на тестах прогонять чтобы выяснить значение 10 (которая с потолка^^)...а в AS3 ничего нового по этой теме нет?

mooncar
18.07.2009, 01:06
Странно, а кроме такого ненадежного способа, как по времени, определить, что данная долговыполняющаяся функция отработана, разве нет? Что-то там в конце же эта функция же должна выдавать?

silin
18.07.2009, 01:30
>>получается надо её сначала на тестах прогонять чтобы выяснить значение 10

не совсем так, 10 это не время выполнения функции, а максимальная ошибка таймера, она на всех машинах примерно такая будет..

вот еще почти такой же вариант
сбрасываем флаг с некоторой задержкой, чтобы дать возможность кликам из очереди сработать вхолостую:
var block:Boolean = false;
function onMouseDown()
{

if (block) return;
block = true;
test();
_global["setTimeout"](this, "unblock", 10);
}
function unblock()
{
block = false;
}

Avid
18.07.2009, 01:39
function onMouseDown(){
enabled=false;
}
function onEnterFrame(){
if(enabled==false){
долговыполняющаяся_функция();
enabled=true;
}
}
вот и весь код, после констуктора кнопки переопредели эти методы эти и все)))

Psycho Tiger
18.07.2009, 09:29
Avid, занимать onEnterFrame для этого - как минимум маразм.
И почитай что написал silin, не сработает твой вариант.

nOobCrafter
20.07.2009, 14:35
DevastT
var block:Boolean = false;
function onMouseDown()
{
if (block) return;
block = true;
долговыполняющаяся_функция();
}
function долговыполняющаяся_функция()
{
....................
block = false;
}
а если так?.. Сделать флаг видимым для обоих функций и менять уже из тормозящей функции в самом конце?.. Тут по идее должно адекватно отработать?

dimarik
20.07.2009, 16:51
nOobCrafter, прочитайте еще раз, внимательно, пост No 4.

iflamberg
20.07.2009, 17:13
var iterations:Number=999999999;

function gigantic ():Boolean{
var t:int = getTimer();
while (iterations--){
if (getTimer()-t>100){ //что-то долго очень в цикле выполняем, нужно бы и другим элементам дать отработать
return false;
}
}
return true;
}

function enterFrameHandler (e:Event):void {
if (gigantic()) {
removeEventListener (Event.ENTER_FRAME,enterFrameHandler);
trace ("длительная функция закончила выполнение");
}
}

addEventListener (Event.ENTER_FRAME,enterFrameHandler);


и никаких проблем с подвисанием на время выполнения длинных функций