MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Какво се случва с Meteor и Fibers/bindEnvironment()?

Използвате bindEnvironment малко неправилно. Защото мястото, където се използва, вече е във влакно и обратното извикване, което идва от клиента на Knox, вече не е във влакно.

Има два случая на използване на bindEnvironment (за които се сещам, може да има още!):

  • Имате глобална променлива, която трябва да бъде променена, но не искате тя да засяга сесиите на други потребители

  • Вие управлявате обратно повикване с помощта на модул api/npm на трета страна (което изглежда е така)

Meteor.bindEnvironment създава ново Fiber и копира текущите променливи и средата на Fiber в новото Fiber. Това, от което се нуждаете, е, когато използвате обратното извикване на метода на вашия nom модул.

За щастие има алтернатива, която се грижи за чакащото ви обратно извикване и свързва обратното извикване във влакно, наречено Meteor.wrapAsync .

Така че можете да направите това:

Функцията ви за стартиране вече има влакно и няма обратно извикване, така че нямате нужда от bindEnvironment тук.

Meteor.startup(function () {
   if (Projects.find().count() === 0) {
     insertRecords();
   }
});

И вашата функция за вмъкване на записи (използвайки wrapAsync), така че нямате нужда от обратно извикване

function insertRecords() {
  console.log("inserting...");
  var client = Knox.createClient({
    key: apikey,
    secret: secret,
    bucket: 'profile-testing'
  });
      
  client.listSync = Meteor.wrapAsync(client.list.bind(client));

  console.log("created client");
      
  try {
      var data = client.listSync({ prefix: 'projects' });
  }
  catch(e) {
      console.log(e);
  }    

  if(!data) return;


  for (var i = 1; i < data.Contents.length; i++)  {
    console.log(data.Contents[i].Key);
    if (data.Contents[i].Key.split('/').pop() == "") {
      Projects.insert({ name: data.Contents[i].Key, contents: [] });
    } else if (data.Contents[i].Key.split('.').pop() == "jpg") {
      Projects.update( { name: data.Contents[i].Key.substr(0,
                         data.Contents[i].Key.lastIndexOf('.')) },
                       { $push: {contents: data.Contents[i].Key}} );
    } else {
      console.log(data.Contents[i].Key.split('.').pop());
    }
  }      
});

Няколко неща, които трябва да имате предвид. Влакната не са като нишки. В NodeJS има само една нишка.

Влакната са по-скоро събития, които могат да се изпълняват по едно и също време, но без да се блокират взаимно, ако има сценарий от тип на изчакване (напр. изтегляне на файл от интернет).

Така че можете да имате синхронен код и да не блокирате събитията на другия потребител. Те се редуват, за да бягат, но все пак работят в една нишка. Ето как Meteor има синхронен код от страна на сървъра, който може да чака за неща, но други потребители няма да бъдат блокирани от това и могат да правят неща, защото техният код работи в различно влакно.

Крис Матер има няколко добри статии за това на http://eventedmind.com

Какво прави Meteor.wrapAsync?

Meteor.wrapAsync приема метода, който сте му дали като първи параметър, и го изпълнява в текущото влакно.

Той също така прикачва обратно извикване към него (предполага, че методът приема последен параметър, който има обратно извикване, където първият параметър е грешка, а вторият резултат като function(err,result) .

Обратното извикване е обвързано с Meteor.bindEnvironment и блокира текущото Fiber, докато не бъде задействано обратното повикване. Веднага след като се задейства обратното извикване, той връща result или хвърля err .

Така че е много удобно за конвертиране на асинхронен код в синхронен код, тъй като можете да използвате резултата от метода на следващия ред, вместо да използвате обратно извикване и да влагате по-дълбоки функции. Той също така се грижи за bindEnvironment вместо вас, така че не е нужно да се притеснявате, че ще загубите обхвата на вашето влакно.

Актуализиране Meteor._wrapAsync вече е Meteor.wrapAsync и документирано.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Задаване на време на изтичане на колекция в mongodb с помощта на mongoose

  2. Комбинирайте пълния текст с друг индекс

  3. Изтриване на каскаден стил в Mongoose

  4. Име на полето batchSize се игнорира в Field Projection

  5. Изтрийте ключ от документ на MongoDB с помощта на Mongoose