2015-12-04 5 views
0

Добрый день. Был разрушен «ol noggin», чтобы решить этот вопрос.Метеор синхронный вызов функции

В двух словах, у меня есть форма, в которой есть несколько текстовых входов, а также элемент входного файла для загрузки указанного файла в AWS S3 (через пакет lepozepo: s3 ver5.1.4). Самое приятное в этом пакете состоит в том, что ему не нужен сервер, тем самым сохраняя ресурсы под контролем.

Этот пакет S3 загружает файл в мое сконфигурированное ведро и возвращает URL-адрес для доступа к изображению среди нескольких других точек данных.

Итак, вернемся к форме. Мне нужно вернуть URL AWS в базу данных вместе с другими данными формы. ОДНАКО, вызов S3 занимает больше времени, чем ожидаемое приложение, так как оно асинхронно, поэтому поле в моем сообщении в Meteor.call() не определено только потому, что оно не дождалось достаточно долго, чтобы получить URL AWS.

Я мог бы решить это, поставив Meteor.call() прямо в обратный вызов вызова S3. Тем не менее, я надеялся избежать этого, так как я предпочел бы, чтобы загрузка S3 была его собственным модулем или вспомогательной функцией или даже функцией вне любых помощников, поскольку ее можно было повторно использовать в других областях приложения для загрузки файлов.

Psudo-код:

Template.contacts.events({ 
    'submit #updateContact': function(e,template){ 
    s3.upload({file:inputFile, path:client},function(error,result){ 
     if(error){ 
     // throw error 
     }else{ 
     var uploadInfo = result; 
     } 
    }); 
    formInfo = {name:$('[name=name]').val(),file:uploadInfo}; // <= file is undefined because S3 hasn't finished yet 
    Meteor.call('serverMethod',formInfo, function(e,r){ 
     if(e){ 
      // throw error message 
     }else{ 
      // show success message 
     } 
    }); 
}); 

я мог бы поставить formInfo и Meteor.call() в s3 обратного вызова, но это приведет к более сложному коду и меньше повторному использованию кода, в котором ИМО это идеальное место для повторного использования коды ,

Я пробовал обернуть s3 в своей собственной функции с обратным вызовом и без него. Я пробовал использовать reactiveVars. Я бы подумал, что обновление db в другой раз только с информацией о файле s3 сделает сложную абстракцию s3 более сложной, так как ей нужно будет знать _id и т. Д.

Любые идеи? Спасибо.

ответ

0

Если вы используете javascript, лучше всего использовать обратные вызовы! Что это такое с использованием обратных вызовов, которые вам не нравятся, или считают, что они модульные или многоразовые?

Как показано ниже, функция uploader делает только перенос s3.upload. Но вы упомянули, что это psudeocode, поэтому я полагаю, что вы оставили логику, которую хотите включить в модульный вызов s3.upload (включите его здесь), но отделите логику вокруг обработки ответа (перейдите в обратный вызов).

uploader = function(s3_options, cb) { 
    s3.upload(s3_options, function(error,result){ 
    if(error){ 
     cb(error); 
    }else{ 
     cb(null, result); 
    } 
    }); 
}; 

Template.contacts.events({ 
    'submit #updateContact': function(e,template){ 

    cb = function(error, uploadInfo) { 
     formInfo = {name:$('[name=name]').val(),file:uploadInfo}; 
     Meteor.call('serverMethod',formInfo, function(e,r){ 
     if(e){ 
     // throw error message 
     }else{ 
     // show success message 
     } 
    }); 
    uploader({file:inputFile, path:client}, cb); // you don't show where `inputFile` or `client` come from 
    } 
}); 
+0

Спасибо. Работает. Мои поиски модульности немного больше, чем я предполагал, я описал это, но это помогает решить небольшую проблему. У меня был S3 в его собственной функции, но я возвращал результат вместо вызова другой функции 'cb = function()', чтобы заставить ее ждать результата S3. Благодарю. (О, и у меня нет проблем, и широко используются обратные вызовы). – dmayo

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