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