2016-01-26 3 views
4

Мой клиент делает звонок на сервер.Как выполнить обратный вызов метода метеоров, который выполняет асинхронные вызовы?

Meteor.call('someRequest', params, onAllDoneCallback); 

, который обрабатывается (код сервера)

Meteor.methods({ 
    'someRequest': function(params, cb) { 
     anAsyncFunction(params, cb); 
     return true; 
    }, 
}); 

Я хотел бы, чтобы onAllDoneCallback быть вызвано на стороне клиента, как только anAsyncFunction закончил и запускает свой собственный обратный вызов.

Однако в Метеор, кажется, что второй аргумент someRequest игнорируется, и что onAllDoneCallback срабатывает с тем, что someRequest возвращается, который здесь true и который вызывается перед тем, что anAsyncFunction закончил.

В моем случае меня больше беспокоит проблема синхронизации (я использую ее, чтобы сообщить клиенту, что обработка завершена, а не только, что запрос хорошо принят), но другие, вероятно, захотят позвонить обратный вызов с аргументами от anAsyncFunction

+0

вы должны вернуть свой результат в обратном вызове вместо возврата True. – MrE

ответ

3

Что вы сейчас делаете, это передать функцию на сервер. Если это делает работы, это очень небезопасно. То, что вы хотите сделать, это создать будущее, а затем использовать его для управления асинхронной функцией. Ниже приведен пример:

let Future = Npm.require('fibers/future'); 
Meteor.methods({ 
    someRequest: function (someArg) { 
    // for security reasons, make sure you check the type of arguments. 
    check(someArg, String); 

    // future is an async handler. 
    let future = new Future(); 
    // this is a function for a generic node style callback [ie, function (err, res)] 
    let resolver = future.resolver(); 

    // run your function and pass it the future resolver 
    // the future will be resolved when the callback happens. 
    anAsyncFunction(someArg, resolver); 

    // this meteor method will not end until future has been resolved. 
    return future.wait(); 
    } 
}); 

В качестве альтернативы, Метеор обеспечивает wrapAsync, который обеспечивает аналогичные функциональные возможности оберточной функции в асинхронных фьючерсах, чтобы они могли работать в методах метеора. То есть:

let wrappedAsyncFunction = Meteor.wrapAsync(anAsyncFunction /** second argument is `this` binding*/); 
return wrappedAsyncFunction(); 
+0

Я только что нашел об этом! Что вы думаете о 'future' vs' wrapAsync'? https://themeteorchef.com/snippets/synchronous-methods/#tmc-using-wrapasync, по-видимому, рекомендует «wrapAsync» как хорошее значение по умолчанию. – Guig

+1

Если вам требуется более подробный контроль над «потоком» выполнения, то вам очень полезно знать как работают фьючерсы. Например, если вы используете «EventEmitter» и вам нужно отключить прослушиватели после разрешения. [Это руководство] (https://gist.github.com/possibilities/3443021) было для меня спасением жизни при использовании будущих оберток метеора, хорошо держать вас с собой – corvid

+0

супер хорошая ссылка – Guig

0

адаптируя этот ответ: Meteor: Proper use of Meteor.wrapAsync on server

Вы должны использовать Meteor «ы wrapAsyncapi, которая принимает функцию, которая принимает функцию обратного вызова в качестве последнего аргумента, обратного вызова будучи как function(error, result){}. Итак, это будет выглядеть так:

Meteor.methods({ 
    'someRequest': function(params){ 
     var wrap = Meteor.wrapAsync(anAsyncFunction); 
     return wrap(params); 
    }, 
});