Node.js — вызов метода после полного выполнения другого метода

У меня есть 2 простых метода:

 function do(x,y){
   if(x){
    XHR1().success();
   }
   if(y){
    XHR2().success();
   }
}

function done(){
   return something;
}

теперь я просто хочу быть уверенным, что вызову done(), когда do() завершится (**метод do() содержит асинхронные запросы к базе данных Mysql)

как я могу этого добиться?**

Очевидно, что это не поставит такие методы в последовательность:

do(x=1,y=1);

done(); //this can run also if do() has not finished yet

Итак, я попытался:

function do(x,y,_callback){
       if(x){
        XHR1().success();
       }
       if(y){
        XHR2().success();
       }

      _callback();
    }

    function done(){
       return something;
    }

do(x=1,y=1,done()); // this won't work the same cause callback is not dependent by XHR response

это то, что я использую для промисов https://github.com/tildeio/rsvp.js/#arrays-of-promises


person itsme    schedule 20.02.2014    source источник
comment
Используйте обратный вызов или обещание.   -  person Matt Ball    schedule 20.02.2014
comment
@Matt Ball обещание в порядке, но я не могу понять, как его решить, если у меня более 1 асинхронного вызова в do ()   -  person itsme    schedule 20.02.2014
comment
вы должны поместить каждый обратный вызов внутри предыдущего. Все, что находится за пределами обратного вызова, будет выполнено немедленно.   -  person Jake Sellers    schedule 20.02.2014


Ответы (3)


я знаю о промисах, но не могу понять, как поместить это в синтаксис

Предполагая, что XHR() действительно возвращает обещание, ваш код должен выглядеть следующим образом:

function do(x,y) {
    var requests = [];
    if (x)
        requests.push( XHR1() );
    if (y)
        requests.push( XHR2() );
    return RSVP.all(requests);
}
function done(){
    return something;
}

do(1, 1).then(done);
person Bergi    schedule 20.02.2014
comment
спасибо, чувак, мне это нужно, я использую RSVP.js github.com/ tildeio/rsvp.js/#массивы-обещаний - person itsme; 20.02.2014

Поскольку node.js по своей природе асинхронен, обычный императивный поток управления больше не работает. У вас есть несколько вариантов, из которых 2 наиболее широко используются.

  1. Обратные вызовы. Вы можете передать второй метод в качестве аргумента первому. Затем в первом выполните переданный обратный вызов, как только задача будет выполнена. Недостаток этого подхода обычно называют «адом обратных вызовов» в сообществе узлов. Если методов не 2, а больше, то приходится передавать и вкладывать колбэки все больше и больше, создавая огромную вложенную структуру.

  2. Используйте обещания. Существует множество библиотек, реализующих шаблон обещаний. Короче говоря, обещания позволяют вам возвращать объект Promise из каждого метода. Промис — это объект, который завершит свою работу в будущем. Он позволяет вам вызывать для него методы, сообщая ему, что должно произойти после его завершения. Взгляните на эту статью для получения дополнительной информации: Понимание промисов в node.js

person Slavo    schedule 20.02.2014
comment
пожалуйста, проверьте вопрос обновлен более чистый код, я знаю, что обещания и обратные вызовы являются решениями, но я не могу понять, как поместить его в синтаксис, пожалуйста, помогите мне - person itsme; 20.02.2014

Популярным шаблоном для асинхронных методов является.

asyncFunc1(arguments, function(err, data){
    if(err) throw err;

    // Do your stuff
});


function asyncFunc1(arguments, callback) {
    asyncFunc2(arg, function(err, data) {
        if(err) return callback(err);

        // Do your stuff

        callback(null, result);
    });
}

См. пример: fs.readFile();

Редактировать

Все еще используя обратные вызовы, но не тот конкретный шаблон, который вы могли бы использовать примерно так:

function do(x,y,_callback){
  var count = 0;

  if(x){
    count++;
    XHR1().success(checkDone);
  }
  if(y){
    count++;
    XHR2().success(checkDone);
  }

  function checkDone(){
    count--;
    if(!count) _callback();
  }
}

function done(){
   return something;
}

do(x=1,y=1,done());

Счетчик отслеживает, сколько асинхронных вызовов вы сделали, и вызывает _callback, когда все сделано. Но вам нужно добавить обратный вызов к XHR().success() методам.

person pstenstrm    schedule 20.02.2014
comment
да, но что, если у вас есть функция 1(){ if(x= 0){ async1() } if(y=0){ async2()} ?? они должны быть разделены, я не могу включить async2 в async 1 - person itsme; 20.02.2014
comment
не совсем уверен, поймали ли вы проблему, я обновил вопрос с более чистым кодом, спасибо - person itsme; 20.02.2014
comment
@pstenstrm Функция asyncFunc2 не определена, и ссылка не работает. Можете ли вы уточнить на реальном примере? - person Manohar Reddy Poreddy; 10.01.2018