2015-09-15 22 views
7

zbudowałem prosty skrypt węzła przy użyciu nightmare.js zeskrobać internetoweStosować Nightmare.js bez składni ES6 i dają

var Nightmare = require('nightmare'); 
var vo = require('vo'); 

vo(run)(function(err, result) { 
    if (err) throw err; 
}); 

function *run() { 
    var x = Date.now(); 
    var nightmare = Nightmare(); 
    var html = yield nightmare 
    .goto('http://google.com') 
    .evaluate(function() { 
     return document.getElementsByTagName('html')[0].innerHTML; 
    }); 

    console.log("done in " + (Date.now()-x) + "ms"); 
    console.log("result", html); 

    yield nightmare.end(); 
} 

chcę uruchomić to w środowisku, za pomocą starszej wersji węzła, który nie robi obsługa funkcji ES6. Na stronie github nie ma przykładów, jak to zrobić bez słowa kluczowego "yield".

znalazłem przykład użycia bez składni ES6 tutaj: Webscraping with nightmare

Napisałem to tak:

var night = new Nightmare() 
.goto('http://www.google.com') 
.evaluate(function() { 
    return document.getElementsByTagName('html')[0].innerHTML; 
},function (html) { 
    console.log("result", html); 
    } 
) 
.run(function (err, nightmare) { 
    if (err) return console.log(err); 
    console.log('Done!'); 
}); 

To nie psuje, ale funkcja rejestrowania wynik nigdy nie jest wywoływana.

Przy użyciu składni plonów, uzyskanie zwróconej wartości z "oceny" jest całkiem proste:, ale bez niego nie znalazłem żadnego sposobu, aby to zrobić.

UPDATE Napisałem to dzięki zaakceptowanej odpowiedzi i jej uwagom. Wykorzystuje „Q” i pracuje w poprzednich wersjach węzłów do 0,12:

var Nightmare = require('nightmare'); 

var Promise = require('q').Promise; 

var x = Date.now(); 
var nightmare = Nightmare(); 
Promise.resolve(nightmare 
    .goto('http://google.com') 
    .evaluate(function() { 
     return document.getElementsByTagName('html')[0].innerHTML; 
})).then(function(html) { 
    console.log("done in " + (Date.now()-x) + "ms"); 
    console.log("result", html); 
    return nightmare.end(); 
}).then(function(result) { 

}, function(err) { 
    console.error(err); // notice that `throw`ing in here doesn't work 
}); 
+1

Używając [Babel węzeł] (https://babeljs.io/docs/usage/cli/# babel-node) może być prostszym rozwiązaniem, w zależności od twojego przypadku użycia. Jest to w zasadzie opakowanie, które przenosi kod ES6 do ES5 przed uruchomieniem go. –

Odpowiedz

12

Docs są straszne, ale wydaje się, że koszmar jest oparta na thenables. Nie znalazłem też wiele informacji na temat interfejsu wywołania zwrotnego, ale i tak doprowadziłoby to do piramidy wcięć.

Więc najlepiej jest użyć obietnic, po prostu wybierz any library, który z grubsza odpowiada standardowi ES6 (wszystkie są użyteczne również w środowiskach innych niż ES6).

można łatwo przekształcić swój liniowy generator kodu do łańcucha obietnicy, wystarczy zastąpić każdą yield przez then rozmowy:

var Nightmare = require('nightmare'); 
var Promise = require('…'); 

var x = Date.now(); 
var nightmare = Nightmare(); 
Promise.resolve(nightmare 
    .goto('http://google.com') 
    .evaluate(function() { 
     return document.getElementsByTagName('html')[0].innerHTML; 
})).then(function(html) { 
    console.log("done in " + (Date.now()-x) + "ms"); 
    console.log("result", html); 
    return nightmare.end(); 
}).then(function(result) { 
    … 
}, function(err) { 
    console.error(err); // notice that `throw`ing in here doesn't work 
}); 
+0

Której biblioteki listy użyłeś w tym dokładnym przykładzie? Próbowałem z "q" bez powodzenia – Rayjax

+0

Ah, 'Q' ma starsze konwencje wywoływania (była to jedna z najwcześniejszych bibliotek). Trzeba by zrobić 'Q.Promise' zamiast' Promise' i 'Q' zamiast' Promise.resolve'. – Bergi

+0

To działa teraz :) – Rayjax

Powiązane problemy