These are chat archives for rosshinkley/nightmare

20th
Jun 2016
Ross Hinkley
@rosshinkley
Jun 20 2016 12:54
@GeoffreyEmery what are you trying to do?
Aaron Rosenberg
@agrberg
Jun 20 2016 18:45

Hey @rosshinkley I have a couple of questions about the multiple steps example when you have a sec:

  • I believe that then:L25 is the then defined on Nightmare that returns a promise in the process of being resolved. So the argument to it, result, is the return value of the last action in the Nightmare queue or evaluate from line 20. The next then is defined by the Promise library and uses the closed over nightmare instance to queue more actions. How is it that then:L39's argument result is not the nightmare instance?

  • nightmare.end() cleans up and shuts down Electron but I don't know why it is defined.

I'm also having a hard time understanding the comments. I just read up on Promises again and it looks like they follow something like .then(func1 { return result1 }).then(func2(result1) { return result2 }) but the thens themselves immediately return the promise object for additional chaining

Ross Hinkley
@rosshinkley
Jun 20 2016 18:49
@agrberg i'll try to take these in order...
re L25, you're right, and you're also right that the next .then() closes over nightmare... but remember how the return value is what the promise resolves to?
The L28 .then() ... cheats? for want of a better word? by returning the Nightmare thenable
which is what the L39 .then() is calling
which is why result is the result from the .evaluate() instead of the Nightmare instance
... does that make sense?
re nightmare.end() and not knowing why it's defined... not sure i follow. It's queued and returned for execution by the next .then().
Aaron Rosenberg
@agrberg
Jun 20 2016 18:56
I meant to ask why end was returned ... didn't proof read enough
Ross Hinkley
@rosshinkley
Jun 20 2016 18:56
ah, i gotcha
that's what i thought, but i figured i'd clarify more before going off in the wrong direction :)
Aaron Rosenberg
@agrberg
Jun 20 2016 18:57
:thumbsup:
what you're saying makes sense with what I've observed but I don't understand how the L28 .then() cheats
Ross Hinkley
@rosshinkley
Jun 20 2016 18:57
... it might make more sense if we take Nightmare out of things entirely and focus just on promises
Aaron Rosenberg
@agrberg
Jun 20 2016 18:59
Sure. I'm certainly no expert there
I think have a basic grasp but that might be it
I've used them really only for XHRs in frontend JS
Ross Hinkley
@rosshinkley
Jun 20 2016 19:00
totally understand. My grasp is also fairly tenuous
but i think i can throw something together to get my point across :)
Ross Hinkley
@rosshinkley
Jun 20 2016 19:05
something like...
Promise.resolve('hello')
    .then(function(msg){
        return msg + ' world';
    })
    .then(function(msg){
        return new Promise(function(resolve){
            resolve(msg + ' again');
        });
    })
    .then(function(msg){
        console.log(msg);
    });
functionally, this is very similar
since the first resolution is not a thennable, the promise will pass the return value straight on through
the second then resolves to a promise... which in turn makes the third then wait for the resolution of the returned promise of the second
... i worded that poorly, but hopefully that makes sense
Aaron Rosenberg
@agrberg
Jun 20 2016 19:08
The first resolution is the first then?
or the resolve?
Ross Hinkley
@rosshinkley
Jun 20 2016 19:08
sorry, i should have been more specific... the first .then() "resolves" by returning a value
in this case, a string
Aaron Rosenberg
@agrberg
Jun 20 2016 19:09
"hello world"
Ross Hinkley
@rosshinkley
Jun 20 2016 19:09
yes
Aaron Rosenberg
@agrberg
Jun 20 2016 19:09
which then would become msg in the function passed to the 2nd then
Ross Hinkley
@rosshinkley
Jun 20 2016 19:09
correct
Aaron Rosenberg
@agrberg
Jun 20 2016 19:10
here's where I get lost
the method to the 2nd then is then evaluated and it returns a new promise that resolves with the string "hello world again"
but my expectation would be that the 2nd Promise would become the msg in the final then
Ross Hinkley
@rosshinkley
Jun 20 2016 19:13
buuuut since the second Promise is thenable... that's what .then() is called on
it's an easy way to guarantee execution order
without a ton of clutter
Aaron Rosenberg
@agrberg
Jun 20 2016 19:14
so even though the final then is chained on to the previous, it is not called on the return of the 2nd then but on the return value of the 2nd then's handler (<-- better word for this?)
Ross Hinkley
@rosshinkley
Jun 20 2016 19:14
if it can be then'd, yes
(at least, that's my understanding, i'm sure this is spelled out in terrifyingly precise and dry detail in the A+ spec)
Aaron Rosenberg
@agrberg
Jun 20 2016 19:15
I may have to read that to get it all straight in my head or just accept the JS magic for the moment :P
Ross Hinkley
@rosshinkley
Jun 20 2016 19:15
hahaha
that "magic" is why you can return a Nightmare chain with the expectation that the next .then() will run it
as nightmare implements .then()
Aaron Rosenberg
@agrberg
Jun 20 2016 19:16
if I replaced the 2nd then's Promise creation with return {then: function() { //whatever }} would that receive the final then since it has a then property/function or are thenables more complex than that?
Ross Hinkley
@rosshinkley
Jun 20 2016 19:17
off the top of my head... i'm not sure
for science
Aaron Rosenberg
@agrberg
Jun 20 2016 19:18
no prob, I'm basing it off of the fact that Nightmare#evaluate returns the nightmare instance which responds to then
I'll give it a try but I think I also need to read this spec
It's a little harder since it breaks my usual rubric for JS reading where everything is parsed and executed and then all the async stuff happens
Ross Hinkley
@rosshinkley
Jun 20 2016 19:19
mhm
Aaron Rosenberg
@agrberg
Jun 20 2016 19:20
so returning nightmare.end() is the same thing since that returns nightmare which is thenable
Ross Hinkley
@rosshinkley
Jun 20 2016 19:20
yep
fwiw, it looks like .then() has the same shape as a promise, it takes a resolve (and optional reject) function
something like...
Promise.resolve('hello')
    .then(function(msg) {
        return msg + ' world';
    })
    .then(function(msg) {
        return {
            then: (resolve) => resolve(msg + ' again')
        }
    })
    .then(function(msg) {
        console.log(msg);
    });
which makes sense
if i had thought about it a little more, i probably could have come up with that, but it's more fun to experiment :P
Ross Hinkley
@rosshinkley
Jun 20 2016 19:25
uuuunsurprisingly, now that i've opened the Nightmare source, that's how Nightmare.then() is set up
Aaron Rosenberg
@agrberg
Jun 20 2016 19:26
yeah I saw the promise in there but I was far lost at that point
Ross Hinkley
@rosshinkley
Jun 20 2016 19:26
i understand :)
well, you're on with ross, and i'm trying to help ;)
Aaron Rosenberg
@agrberg
Jun 20 2016 19:26
I appreciate it!
when you say it guarantees execution order
sry hit enter too soon
don't thens execute in order?
oh but nightmare is async so it guarantees the first queue finishes before the next's
Ross Hinkley
@rosshinkley
Jun 20 2016 19:32
in general, yes.
(there are some circumstances where you can do unsavory things with the queue.)
Aaron Rosenberg
@agrberg
Jun 20 2016 19:38
last question for the moment, is there a way to get better output when something is wrong? For example I was a derp and misspelled evaluate. I didn't see anything except the electron window opening and immediately closing. I cannot remember if I added a catch at the end of the then chain like in the example before or after this.
Ross Hinkley
@rosshinkley
Jun 20 2016 19:39
.catch(), also using DEBUG=nightmare*,electron* will probably be of use to you
Aaron Rosenberg
@agrberg
Jun 20 2016 19:40
I've just been using DEBUG=nightmare* I'll add the electron one :thumbsup:
Ross Hinkley
@rosshinkley
Jun 20 2016 19:40
:)
fwiw, you could also be liberal with your debug rules and go for DEBUG=*, but in general, i don't like to do that, especially if you're using express, mocha, or nodemon
Aaron Rosenberg
@agrberg
Jun 20 2016 19:43
I'm getting plenty of output without it :P
Ross Hinkley
@rosshinkley
Jun 20 2016 19:44
indeed
Brandon Wilhite
@JediMindtrick
Jun 20 2016 21:23
hiya, has anyone had experience using nightmare on aws lambda?
does it sound like a plausible idea?
Ross Hinkley
@rosshinkley
Jun 20 2016 22:54
i don't have any experience personally, but a quick glance through the docs... you'll need to make sure the image has xvfb and node 4+, but otherwise, it should work
you might also want to have a read through segmentio/nightmare#224
(i can't recall offhand if aws lambda was hit there or not, but still may be relevant to your interests)