возвращающая ошибка из обещания в angularjs [duplicate]

Первым делом, вероятно, будет замена каждого вызова функции mysql_* с его эквивалентом mysqli_*, по крайней мере, если вы захотите использовать процедурный API, что было бы проще, учитывая, что у вас уже есть некоторый код, основанный на API MySQL, который является процедурным.

Чтобы помочь в этом, Краткое описание функции расширения MySQLi , безусловно, будет полезным.

Например:

Обратите внимание, что для некоторых функций вам может потребоваться тщательно проверить параметры: может быть, есть некоторые различия здесь и там - но не это многие, я бы сказал: и mysql, и mysqli основаны на одной и той же библиотеке (libmysql; по крайней мере, для PHP & lt; = 5.2)

Например:

  • с mysql, вы hav e использовать один раз подключенный mysql_select_db , чтобы указать, в какой базе данных вы хотите выполнять свои запросы
  • mysqli, с другой стороны, позволяет указать это имя базы данных как четвертый параметр mysqli_connect .
  • Тем не менее, есть также функция mysqli_select_db , которую вы можете использовать, если хотите.

Как только вы закончите с этим, попробуйте выполнить новую версию своего скрипта ... И проверьте, все ли работает; если нет ... Время для поиска ошибок; -)

27
задан Jordan 5 May 2013 в 21:51
поделиться

3 ответа

Для меня этот результат не имеет смысла. Присоединившись к этой цепочке обещаний, каждый из них подразумевает, что он будет зависеть от успешного разрешения d1 и результата, передаваемого по цепочке

No. То, что вы описываете, не является цепочкой, а просто привязывает все обратные вызовы к d1. Тем не менее, если вы хотите связать что-то с then, результат для promise2 зависит от разрешения promise1 и того, как обратные вызовы then обрабатывали его .

Состояние docs:

Возвращает новое обещание для результата обратного вызова.

Метод .then обычно рассматривается в терминах спецификации Promises / A (или даже более строгая Promsises / A + one ). Это означает, что обратные вызовы возвращают обещания, которые будут ассимилированы, чтобы стать разрешением promise2, и если обработчик успеха / ошибки не будет получен, соответствующий результат будет передан непосредственно в promise2 - поэтому вы можете просто опустить обработчик для распространения ошибки.

Тем не менее, если ошибка обработана , результат promise2 рассматривается как фиксированный и будет выполняться с этим значением. Если вы этого не хотите, вам придется повторно throw ошибка, как в предложении try-catch. В качестве альтернативы вы можете вернуть (отправленное) отклоненное обещание от обработчика. Не уверен, что Dojo способ отклонить, но:

var d1 = d();

var promise1 = d1.promise.then(
    function(wins) { console.log('promise1 resolved'); return wins;},
    function(err) { console.log('promise1 rejected'); throw err;});
var promise2 = promise1.then(
    function(wins) { console.log('promise2 resolved'); return wins;},
    function(err) { console.log('promise2 rejected'); throw err;});
var promise3 = promise2.then(
    function(wins) { console.log('promise3 resolved'); return wins;},
    function(err) { console.log('promise3 rejected'); throw err;});
d1.reject(new Error());

Как Боб может получить синий виджет от Имбиря, когда сам не получил?

Он не должен уметь. Если обработчиков ошибок нет, он просто воспримет сообщение ((от дистрибутора) от Джона) от Ginger), что никаких виджетов не осталось. Тем не менее, если Джинджер настраивает обработчик ошибок для этого случая, она все равно может выполнить свое обещание дать Бобу виджет, предоставив ему зеленый цвет из своей собственной хижины, если у Джона или его дистрибьютора нет синих.

Чтобы перевести ваши обратные вызовы в метафору, return err из обработчика просто походило бы на то, чтобы сказать «если нет никаких виджетов, просто дайте ему примечание о том, что их нет, - это так же хорошо, как и желаемое widget ".

В ситуации с базой данных, если db.query завершился с ошибкой, она вызовет функцию err первой, затем

... что будет означать что ошибка обрабатывается там. Если вы этого не сделаете, просто опустите обратный вызов ошибки. Кстати, ваши обратные вызовы не выполняют return обещания, которые они создают, поэтому они кажутся совершенно бесполезными. Правильно было бы:

var promise = db.query({parent_id: value});
promise.then(function(query_result) {
    var first_value = {
        parent_id: query_result[0].parent_id
    }
    var promise = db.put(first_value);
    return promise.then(function(first_value_result) {
        var second_value = {
            reference_to_first_value_id: first_value_result.id
        }
        var promise = db.put(second_value);
        return promise.then(function(second_value_result) {
            return values_successfully_entered();
        });
    });
});

или, поскольку вам не нужны блокировки для доступа к значениям результатов из предыдущих обратных вызовов, даже:

db.query({parent_id: value}).then(function(query_result) {
    return db.put({
        parent_id: query_result[0].parent_id
    });
}).then(function(first_value_result) {
    return db.put({
        reference_to_first_value_id: first_value_result.id
    });
}.then(values_successfully_entered);
26
ответ дан Bergi 27 August 2018 в 07:21
поделиться

Использование может обернуть ошибки на каждом уровне обещания. Я приковал ошибки в TraceError:

class TraceError extends Error {
  constructor(message, ...causes) {
    super(message);

    const stack = Object.getOwnPropertyDescriptor(this, 'stack');

    Object.defineProperty(this, 'stack', {
      get: () => {
        const stacktrace = stack.get.call(this);
        let causeStacktrace = '';

        for (const cause of causes) {
          if (cause.sourceStack) { // trigger lookup
            causeStacktrace += `\n${cause.sourceStack}`;
          } else if (cause instanceof Error) {
            causeStacktrace += `\n${cause.stack}`;
          } else {
            try {
              const json = JSON.stringify(cause, null, 2);
              causeStacktrace += `\n${json.split('\n').join('\n    ')}`;
            } catch (e) {
              causeStacktrace += `\n${cause}`;
              // ignore
            }
          }
        }

        causeStacktrace = causeStacktrace.split('\n').join('\n    ');

        return stacktrace + causeStacktrace;
      }
    });

    // access first error
    Object.defineProperty(this, 'cause', {value: () => causes[0], enumerable: false, writable: false});

    // untested; access cause stack with error.causes()
    Object.defineProperty(this, 'causes', {value: () => causes, enumerable: false, writable: false});
  }
}

Использование

throw new TraceError('Could not set status', srcError, ...otherErrors);

Выход

[/g0]

Функции

TraceError#cause - first error
TraceError#causes - list of chained errors
0
ответ дан bluejamesbond 27 August 2018 в 07:21
поделиться

@ Jordan во-первых, как отмечали комментаторы, при использовании отложенной библиотеки ваш первый пример определенно дает результат, который вы ожидаете:

promise1 rejected
promise2 rejected
promise3 rejected

Во-вторых, даже если он будет производить вывод, который вы предлагаете, это не повлияет поток выполнения вашего второго фрагмента, который немного отличается, больше напоминает:

promise.then(function(first_value) {
    console.log('promise1 resolved');
    var promise = db.put(first_value);
    promise.then(function (second_value) {
         console.log('promise2 resolved');
         var promise = db.put(second_value);
         promise.then(
             function (wins) { console.log('promise3 resolved'); },
             function (err) { console.log('promise3 rejected'); return err; });
    }, function (err) { console.log('promise2 rejected'); return err;});
}, function (err) { console.log('promise1 rejected'); return err});

и что в случае первого отклонения обещания будет просто выводиться:

promise1 rejected

Однако (попадая в самую интересную часть), хотя отложенная библиотека определенно возвращает 3 x rejected, большинство других библиотек обещаний вернут 1 x rejected, 2 x resolved (что приводит к предположению, что вы получили эти результаты, используя вместо этого другую библиотеку обещаний).

Что дополнительно сбивает с толку, эти другие библиотеки более корректны с их поведением. Позвольте мне объяснить.

В синхронизирующей мировой копии «обещания отклонения» есть throw. Таким образом, семантически, синхронизация async deferred.reject(new Error()) равна throw new Error(). В вашем примере вы не бросаете ошибки в своих обратных вызовах синхронизации, вы просто возвращаете их, поэтому вы переключаетесь на поток успеха, причем ошибка является значением успеха. Чтобы убедиться, что отклонение передано дальше, вам нужно повторно выбросить свои ошибки:

function (err) { console.log('promise1 rejected'); throw err; });

Итак, теперь вопрос заключается в том, почему отложенная библиотека приняла возвращенную ошибку как отклонение?

Причина для этого, заключается в том, что отклонение в отложенных работах несколько отличается. В отложенном lib это правило: обещание отвергается, когда оно разрешено с экземпляром ошибки, поэтому, даже если вы deferred.resolve(new Error()), оно будет действовать как deferred.reject(new Error()), и если вы попытаетесь сделать deferred.reject(notAnError), это вызовет исключение, говорящее , это обещание может быть отклонено только с учетом ошибки. Это дает понять, почему ошибка, возвращаемая с then обратного вызова, отвергает обещание.

Существует некоторая обоснованная аргументация отложенной логики, но все же она не соответствует тем, как throw работает на JavaScript, и из-за этого это поведение запланировано для изменения с версией v0.7 отложенных.

Краткий обзор:

Чтобы избежать путаницы и неожиданных результатов, просто следуйте правилам хорошей практики:

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

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

1
ответ дан Mariusz Nowak 27 August 2018 в 07:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: