Как спирате функция, когато се получи обект Error?

Как да спра функцията, когато възникне грешка.

Правя http post call. Създадох функция за обратно извикване в стил „първа грешка“.

Как да спра функцията за обратно извикване, ако в нея е предаден обект Error? В моя случай на употреба трябва да спра независимо от типа на грешката, тъй като имам нужда от обект с данни за последваща верига от функции за обратно извикване.

Дали е просто return? Прочетох какво прави връщането на по-високо ниво, така че се надявам да получа потвърждение дали кодът ми е правилен за това, което бих искал да постигна.

Просто искам да се уверя, че продължаващите функции за обратно извикване не продължават, тъй като няма да им бъдат предавани обекти с данни, следователно всички ще бъдат „грешки“

server.js

var request = function(callback) {
  // HTTP call to server
      },  
      function (error, response, body) {    
      if (!error && response.statusCode === 200) {
        // processed and created data object
          return callback(null, data)
      }
      else {
         console.log(error.stack)
         return callback(error) ;
      }
    })
};
var requestSync = Meteor.wrapAsync(request);


var callback = function(error, data, callback) {
  if (error) {
    // How do I properly stop this function?
     return callback(new Error('custom message I send to client'))
  }
  else {
    // doing something with data object..
  }
}

Функциите се извикват в моя метод.

try {
  var resultOne = requestSync()
  var resultTwo = callback(resultOne)
  // more async callback functions will reside here
} catch (e) {
  console.error('error occured somehwere = ' + e);
} finally {
//
}

person meteorBuzz    schedule 24.02.2015    source източник
comment
Мисля, че това, което търсите, е ключовата дума return във вашето обратно извикване. if (error) return callback(new Error(...)) Или може би throw ключова дума, if (error) throw new Error(...)   -  person SnowInferno    schedule 24.02.2015
comment
Оставих връщането навън по погрешка, но съм любопитен да знам дали това е правилният начин да постигна това, което искам. След това ще мога да адаптирам обработката си на грешки въз основа на контекста в други случаи   -  person meteorBuzz    schedule 24.02.2015


Отговори (2)


Не съм виждал точно този начин на кодиране преди, така че е трудно да коментирам дали това е правилният начин, без да знам малко повече за това, което наистина се опитвате да направите. Предполагам, че блокът:

try {
  var resultOne = requestSync()
  var resultTwo = callback(resultOne)
  // more async callback functions will reside here
} catch (e) {
  console.error('error occured somehwere = ' + e);
} finally {
}

...извиква друга функция за "обратно извикване" от тази в първия кодов фрагмент (или в противен случай предавате resultOne като първи параметър и функцията за обратно извикване ще прочете това като валиден обект за грешка и ще изведе грешка).

Въпреки това, за да отговорим на вашето безпокойство дали кодът ще продължи да работи, ако една от функциите изведе грешка, отговорът е не - той ще се прехвърли директно към catch блока. Разгледайте: тази документация на MDN

Особено тази част:

Клаузата catch съдържа инструкции, които указват какво да се направи, ако в блока try бъде хвърлено изключение. Тоест искате блокът try да успее и ако не успее, искате контролът да премине към блока catch. Ако който и да е израз в блока try (или във функция, извикана от блока try) хвърли изключение, управлението незабавно се прехвърля към клаузата catch. Ако не е хвърлено изключение в блока try, клаузата catch се пропуска.

Надявам се, че това отговаря на основния ви въпрос. Тъй като изглежда обгръщате всички асинхронни извиквания в Meteor.wrapAsync(), те трябва да изчакат резултатът да се върне, преди да извикат следващата функция, ако е внедрена правилно. Мога да препоръчам да погледнете този отговор за повече информация относно правилния начин за внедряване на wrapAsync и обработка на грешки.

АКТУАЛИЗАЦИЯ

Мислех, че е интересно да направя пример, тъй като тази публикация вече става дълга. Разгледайте този пример, който качих в Github, може да ви даде нужните отговори.

И така, обектът „грешка“, върнат обратно от http извикването, винаги ли се разпознава като обект за грешка?

Е, fiber/future предполага стандартно обратно извикване на възел като последен аргумент с обект за грешка като първи параметър и резултатен обект като втори. Докато това е така, грешката ще бъде уловена в блока "catch" и изпълнението ще спре.

Ако е така, как мога да добавя друго поле, така че грешката да има смисъл за мен?

Не съм сигурен какво точно мислите тук, но вижте моя пример в Github. Там създавам обект за грешка. Ако вместо да използвате setTimeout (където просто симулирам асинхронно повикване), конструирайте функцията си по същия начин, хванете обекта за грешка от отдалеченото повикване, добавете поле към него или променете err.message на нещо по-смислено за вас, и след това извикайте обратното извикване. Мисля, че това трябва да работи, но не съм тествал точно това.

Ако има грешка, но не е предаден обект за грешка, каква е конвенцията за възел за създаване на обект за грешка, който мога да върна?

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

Ако по някаква причина искате сами да се справите с обратното извикване, трябва да се уверите, че извиквате обратното извикване ръчно и да подадете „null“ като първи параметър, ако няма грешка, или да създадете обект за грешка и да го предадете като първи параметър, ако има грешка. Вижте wrapAsyncTest.js в примера.

person cfs    schedule 24.02.2015
comment
Да, това е важно, но Meteor.wrapAsync() използва Fibers, за да направи асинхронния код да изглежда като синхронизиран, така че стига да се използва правилно, изразите трябва да се извикват един след друг. Това е нещо като алтернатива на обещанията за предотвратяване на много вложени обратни извиквания. - person cfs; 25.02.2015
comment
И така, обектът „грешка“, върнат обратно от http извикването, винаги ли се разпознава като обект за грешка? Ако е така, как мога да добавя друго поле, така че грешката да има смисъл за мен? АКО има грешка, но не е предаден обект за грешка, каква е конвенцията за възел за създаване на обект за грешка, който мога да върна? Благодаря @cfs за информацията. - person meteorBuzz; 26.02.2015
comment
Тъй като обвих функцията си в Meteor.wrap async и понякога използвах бъдещата библиотека, функцията все още е асинхронна, но поведението на функцията е „като синхронно“. Което означава, че мога да инициирам увития асинхронен код един след друг, където всеки чака резултатите да се върнат и НЕ блокира цикъла на събитията. - person meteorBuzz; 26.02.2015
comment
@cfs, примерът на gutHub, който публикувахте, е много полезен при обяснението на основния процес. Той служи на моята цел да се справя с грешките си. Благодаря ти - person meteorBuzz; 09.03.2015

повече от модел node.js, но ето какво използвам:

if (err) return callback(err, null);
console.log("no error here!");
callback(err, result);
person Matt K    schedule 24.02.2015