Stripe 3d безопасный платеж?

Mutable contextual state

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

function getExample() {
    var resultA;
    return promiseA(…).then(function(_resultA) {
        resultA = _resultA;
        // some processing
        return promiseB(…);
    }).then(function(resultB) {
        // more processing
        return // something using both resultA and resultB
    });
}

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

Это решение имеет несколько Недостатки:

  • Mutable state является уродливым , а глобальные переменные являются злыми .
  • Этот шаблон не работает через функциональные границы, модуляция функций сложнее, так как их объявления не должны выходить из общей области действия
  • . Область переменных не препятствует доступу к ним до их инициализации. Это особенно вероятно для сложных перспективных конструкций (петли, ветвление, выходы), где могут возникать условия гонки. Передавая состояние явно, декларативный дизайн , который обещает поощрять, заставляет более чистый стиль кодирования, который может предотвратить это.
  • Необходимо правильно выбрать область для этих общих переменных. Он должен быть локальным для выполняемой функции, чтобы предотвратить условия гонки между несколькими параллельными вызовами, как это было бы, если бы, например, состояние хранилось на экземпляре.

Библиотека Bluebird поощряет использование объекта, который передается вместе с использованием метода bind() , чтобы назначить объект контекста цепочке обещаний. Он будет доступен из каждой функции обратного вызова через непригодное для использования this ключевое слово . Хотя свойства объекта более подвержены необнаруженным опечаткам, чем переменные, шаблон довольно умный:

function getExample() {
    return promiseA(…)
    .bind({}) // Bluebird only!
    .then(function(resultA) {
        this.resultA = resultA;
        // some processing
        return promiseB(…);
    }).then(function(resultB) {
        // more processing
        return // something using both this.resultA and resultB
    }).bind(); // don't forget to unbind the object if you don't want the
               // caller to access it
}

Этот подход можно легко моделировать в библиотеках обещаний, которые не поддерживают .bind (хотя в несколько более подробных путь и не может использоваться в выражении):

function getExample() {
    var ctx = {};
    return promiseA(…)
    .then(function(resultA) {
        this.resultA = resultA;
        // some processing
        return promiseB(…);
    }.bind(ctx)).then(function(resultB) {
        // more processing
        return // something using both this.resultA and resultB
    }.bind(ctx));
}

-2
задан Mohd Zubair Khan 8 April 2019 в 09:19
поделиться