2012-02-23 2 views
4

Я использую jsdom с jquery, и он работает нормально. Тем не менее, я пытаюсь немного модифицировать свой код, поэтому я не повторяюсь сам, поэтому я сделал основную функцию из некоторого кода jsdom, который принимает некоторые html (DOM), улучшает его с помощью jquery и выплевывает обратно , Однако я не могу вернуть свой результат и, таким образом, назначить его вызову var. Я, вероятно, не вернусь в нужное место, но я просто не вижу очевидного, если так. Может немного помочь.Как вернуть значение из простой функции jsdom?

Вот код:

function tweakIt(html_in){ 
    var jsdom = require('jsdom'); 
    jsdom.env({ 
    html: html_in, 
    scripts: [ 
     '../public/javascripts/jquery-1.7.1.min.js', 
    ], 
    done: function(errors, window) { 
     var $ = window.$; 
     // do some jquery magic and manipulate the dom 
     $('body').append('<div>foo</div>'); 

     console.log('Freshly Manipulated HTML: '+ $('body').html()); // it logs perfectly 
     return $('body').html(); // this isn't returned to where I called tweakIt() from, why not? 
    } 
    }); 
} 

var oldhtml = '<html><body><div>some text</div></body></html>'; 
var newhtml = tweakIt(oldhtml); // never gets set because nothing gets returned, why? 

EDIT:

Это действительно проблема асинхронной, так вот как это должно быть сделано с помощью обратного вызова вместо возврата:

function tweakIt(html_in, callback){ 
    var jsdom = require('jsdom'); 
    jsdom.env({ 
    html: html_in, 
    scripts: [ 
     '../public/javascripts/jquery-1.7.1.min.js', 
    ], 
    done: function(errors, window) { 
     var $ = window.$; 
     // do some jquery magic and manipulate the dom 
     $('body').append('<div>foo</div>'); 

     console.log('Freshly Manipulated HTML: '+ $('body').html()); // it logs perfectly 
     callback($('body').html()); // instead of a return, pass the results to the callback 
    } 
    }); 
} 

var oldhtml = '<html><body><div>some text</div></body></html>'; 
var newhtml = tweakIt(oldhtml, function(newstuff){ 
    console.log(newstuff); // woohoo! it works! 
}); 

ответ

5

Я не думаю, что вы можете сделать это, используя возвращаемое значение, потому что done: is async. Попробуйте добавить обратный вызов к вашему tweakIt и получить новый html, отправив его как параметр, например.

tweakIt(oldHtml, function(newHtml) {/*use the result here*/})

+0

нормально, но как я могу отправить newHtml обратного вызова от 'сделано:'? – k00k

+0

Ничего, я понял. Я отредактирую свой OP, чтобы показать, как это должно быть сделано. Благодаря! – k00k

+1

Предполагая, что вы назвали свой второй параметр в функции tweakIt 'callback', а вместо вашего оператора return в выполненной функции вы сделали бы что-то вроде этого:' callback ($ ('body'). Html()) ' –

0

Новая версия JSDOM API больше не включает в себя «сделано» вариант обратного вызова.

Таким образом, я написал обратный вызов «плохого человека» для доступа к переменной DOM только после ее установки.

function getSomeDOMVar(callback) { 
 

 
    const jsdom = require("jsdom"); 
 
    const { JSDOM } = jsdom; 
 

 
    const dom = new JSDOM(` 
 
    <!DOCTYPE html> 
 
    <html> 
 
     <body> 
 
      <script> 
 
       var result; // globally scoped, undefined var, accessible in the node scope as dom.window.result 
 

 
       function doSomething() { 
 
        // your code goes here 
 
       } 
 

 
       // then assign the data you want back to your the globally scoped var 
 
       result = doSomething(); 
 

 
      </script> 
 
     </body> 
 
    </html> 
 
    `, { 
 
     runScripts: "dangerously", 
 
     resources: "usable" 
 
    }); 
 

 
    // poor man's callback 
 
    function waitForVar() { 
 
     if (typeof dom.window.result !== 'undefined') { 
 
      cb(dom.window.result); 
 
     } 
 
    } 
 
    setTimeout(waitForVar, 1000); 
 
} 
 

 
getSomeDOMVar(function(result) { 
 
    console.log(result) 
 
});

Смежные вопросы