Just in case someone is interested, recursion seems a good choice to 
replace the loop:

sub recur {
    my ($c) = @_;
    my @output = ( "output:" );


    my $max = 100;
    my $i = 0;
    my $run_q;
    $run_q = sub {
        Mojo::IOLoop->timer( 0.25 => sub {
            if ((rand(10) > 8 ) || ($i > $max)) {
                $c->render(text => join(",",  @output) );
                return;
            } else {
                push @output, ++$i;
                $run_q->();
            }
        });
    };
    $run_q->();
}





On Thursday, March 15, 2018 at 3:19:39 PM UTC+8, Michael Fung wrote:
>
> Agree. It's hard to mix asynchronous stuff and loop flow. I will try to 
> look for other ways to run the loop.
>
> On Thursday, March 15, 2018 at 1:26:16 PM UTC+8, Dan Book wrote:
>>
>> The best approach would probably be to rethink your logic to be fully 
>> asynchronous. You should not ever need to wait for results; you should 
>> always do the following actions in further ->then callbacks, or use 
>> Mojo::Promise->all or similar to make promises that wait for several other 
>> promises.
>>
>> -Dan
>>
>> On Thu, Mar 15, 2018 at 12:51 AM, Michael Fung <[email protected]> 
>> wrote:
>>
>>> This is gold:
>>> *"You need to use the same event loop for the promise as for the items 
>>> that will resolve it"*
>>>
>>> Thanks Dan!
>>>
>>> The posted action is just for demo my problem. I actually want to use a 
>>> loop to do something like:
>>>
>>> # inside a timer callback
>>> my $more_jobs = 1;
>>> while ($more_jobs) {
>>>   $get_job->()
>>>   ->then( $run_job )
>>>   ->catch( sub { $more_jobs = 0 } )
>>>   ->wait;
>>> }
>>>
>>>
>>>
>>>
>>> On Thursday, March 15, 2018 at 12:35:16 PM UTC+8, Dan Book wrote:
>>>>
>>>> But to add, there's usually no reason to make it this complicated; if 
>>>> you just use the main event loop, and do your rendering in a ->then 
>>>> chained 
>>>> off the promise, you don't need to wait for it; it will render the page 
>>>> when the promise resolves.
>>>>
>>>> On Thu, Mar 15, 2018 at 12:34 AM, Dan Book <[email protected]> wrote:
>>>>
>>>>> You need to use the same event loop for the promise as for the items 
>>>>> that will resolve it. So for instance in your example you need to do:
>>>>>
>>>>> my $loop = Mojo::IOLoop->new;
>>>>> my $promise = Mojo::Promise->new(ioloop => $loop);
>>>>> $loop->timer(...);
>>>>> return $promise;
>>>>>
>>>>> On Wed, Mar 14, 2018 at 11:34 PM, Michael Fung <[email protected]> 
>>>>> wrote:
>>>>>
>>>>>> Hi Dan, 
>>>>>>
>>>>>> It does not work, perhaps I misunderstood you.
>>>>>>
>>>>>> Here is my action for test:
>>>>>>
>>>>>> sub boom {
>>>>>>     my ($c) = @_;
>>>>>>     my @output;
>>>>>>
>>>>>>
>>>>>>     my $timer = sub {
>>>>>>         #~ my $promise = Mojo::Promise->new;
>>>>>>         my $promise = Mojo::Promise->new(ioloop => Mojo::IOLoop->new
>>>>>> );
>>>>>>         Mojo::IOLoop->timer( 2 => sub {
>>>>>>             $promise->resolve();
>>>>>>         });
>>>>>>         return $promise;
>>>>>>     };
>>>>>>
>>>>>>
>>>>>>     $timer->()
>>>>>>     ->then( sub {
>>>>>>         warn "Boom!";
>>>>>>         push @output, "Boom!";
>>>>>>     } )
>>>>>>     ->wait;
>>>>>>     
>>>>>>     push @output, "-the end- \n";
>>>>>>
>>>>>>
>>>>>>     $c->render(text => join(",", @output) );
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> No matter which  Mojo::Promise->new statement I use, the result is 
>>>>>> the same: I only get "-the end-" without "Boom!".
>>>>>>
>>>>>>
>>>>>> On Thursday, March 15, 2018 at 12:21:12 AM UTC+8, Dan Book wrote:
>>>>>>>
>>>>>>> ->wait will not block if the event loop is currently running, like 
>>>>>>> if you are setting this up in an event loop callback like a request 
>>>>>>> handler. In order to cause promises to block while running the main 
>>>>>>> event 
>>>>>>> loop, you need to run the promises in a separate event loop.
>>>>>>>
>>>>>>> my $promise = Mojo::Promise->new(ioloop => Mojo::IOLoop->new);
>>>>>>>
>>>>>>> On Wed, Mar 14, 2018 at 10:06 AM, Michael Fung <[email protected]> 
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Thanks Andre. I already have the "return $promise" statement to end 
>>>>>>>> the sub, so it is not the cause. 
>>>>>>>>
>>>>>>>> I really suppose the construct will work like the recv function of 
>>>>>>>> AnyEvent->condvar.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wednesday, March 14, 2018 at 9:11:53 PM UTC+8, Andre Parker 
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> Hi.
>>>>>>>>>
>>>>>>>>> You should return promise object in get_data sub. Something like:
>>>>>>>>>
>>>>>>>>> my $get_data = sub {
>>>>>>>>>   my $promise = Mojo::Promise->new();
>>>>>>>>>   # Some code that resolves promise
>>>>>>>>>   ...
>>>>>>>>>   return $promise;
>>>>>>>>> };
>>>>>>>>>
>>>>>>>>> On Wednesday, 14 March 2018 12:18:07 UTC+2, Michael Fung wrote:
>>>>>>>>>>
>>>>>>>>>> Hi all,
>>>>>>>>>>
>>>>>>>>>> I have the following construct using Mojo::Promise:
>>>>>>>>>>
>>>>>>>>>> my $get_data =  sub {
>>>>>>>>>>   create new Promise object;
>>>>>>>>>>   read data from database
>>>>>>>>>>   if data read ok {
>>>>>>>>>>     $promise->resolve($data);
>>>>>>>>>>   } else {
>>>>>>>>>>     $promise->reject('no data');
>>>>>>>>>>   }
>>>>>>>>>> };
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> $get_data->()
>>>>>>>>>> ->then( sub {
>>>>>>>>>>   # do something with data
>>>>>>>>>>   ...
>>>>>>>>>> })
>>>>>>>>>> ->catch( sub {
>>>>>>>>>>   # log error
>>>>>>>>>>   ...
>>>>>>>>>> })
>>>>>>>>>> ->wait;
>>>>>>>>>>
>>>>>>>>>> say "the end";
>>>>>>>>>>
>>>>>>>>>> However, I got *"the end*" before running the "do something with 
>>>>>>>>>> data" block or catch block. Is there any way to make ->wait really 
>>>>>>>>>> wait?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Michael
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> -- 
>>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>>> Groups "Mojolicious" group.
>>>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>>>> send an email to [email protected].
>>>>>>>> To post to this group, send email to [email protected].
>>>>>>>> Visit this group at https://groups.google.com/group/mojolicious.
>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>
>>>>>>>
>>>>>>> -- 
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "Mojolicious" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>> send an email to [email protected].
>>>>>> To post to this group, send email to [email protected].
>>>>>> Visit this group at https://groups.google.com/group/mojolicious.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>>
>>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Mojolicious" group.
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to [email protected].
>>> To post to this group, send email to [email protected].
>>> Visit this group at https://groups.google.com/group/mojolicious.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.

Reply via email to