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] > <javascript:>> 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] <javascript:>. >> To post to this group, send email to [email protected] >> <javascript:>. >> 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.
