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.