2014-11-25 6 views
1

Я использую Node.js с cheerio (модуль jQuery на Node.js) и fetch (модуль, чтобы получить тело HTML, например request), чтобы получить некоторые данные с сайта и сохранить в MongoDB.Как подождать, пока не будут закончены некоторые методы jQuery?

Я могу выбрать элементы, такие как JQuery в браузерах

я должен получить data и передать data к callback функции, что-то вроде:

var data = ""; 
var fetchById = function(id, callback){ 
    var data = $("#"+id).parent().siblings(".someClass").text().replace(/\s/g, ""); // line 3 
    callback(null, data); 
}; 

, а затем ...

fetchById(10987, function(err, data){ 
    if(err){ 
     // errorHandle(err); 
    }else{ 
     // db.save(data); 
    } 
}); 

Но иногда callback вызывается перед тем, как линия 3 успешно прошла trieved data, поэтому data пустая строка ""

Как я могу гарантировать, что callback вызывается после того, как линия 3 закончена?

+6

javascript runes linearly, он не должен запускать «обратный вызов» до того, как закончится 3-я строка, единственным исключением является асинхронный вызов, здесь не выглядит так. – Patrick

+0

Я ожидаю, что вы это сделали, но мы должны быть уверены ... Вы проверили, что только ваша функция 'fetchById' вызывает taht callback? И что единственным вызовом является контекст, который вы сейчас отлаживаете? – Renan

+0

В этом обратном вызове другого вызова не производится. Как уже упоминалось, иногда я успешно получаю данные с помощью методов jQuery, иногда терпит неудачу ... поэтому я думаю, что единственная причина в том, что строка 3 требует разного времени при каждом вызове – kitlee

ответ

0

Вы можете выполнить это путем явного очередности. См. jQuery API.

Например (из API):

$("#foo").slideUp(); 
$("#foo").queue(function() { 
    alert("Animation complete."); 
    $(this).dequeue(); 
}); 

который является таким же, как выполнение .slideUp() первой, а затем, в качестве обратного вызова, выполнение alert().

Как для вас код, это превратится во что-то вроде этого:

var data = 0; 

$("#some_element").queue("yourQueue", function() { 
    console.log("First"); 

    // first function 
    data = $("#"+id).parent().siblings(".someClass").text().replace(/\s/g, ""); 

    $(this).dequeue("yourQueue"); 
}); 

$("#some_element").queue("yourQueue", function() { 
    console.log("Second"); 

    // second function 
    callback(null, data); // if callback() is a declared function, this should work 

    $(this).dequeue("yourQueue"); 
}); 

$("#some_element").dequeue("yourQueue"); 

Где я использовал код из этого ответа: How do I chain or queue custom functions using JQuery?

Важно отметить, что функция .queue() должна быть вызвал на тот же самый глобальный элемент, чтобы убедиться, что функции выполняются (явно) последовательно.

+1

Метод '.queue()' работает для меня! но я переключаюсь на 'jsdom' с jQuery вместо' cheerio' sine, у него нет метода '.queue()' – kitlee

+0

@WhyCode: Хорошо, если вы думаете, что я ответил на ваш вопрос, подумайте о его принятии. –

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