Использование обратных вызовов, соответствующих продолжению в javascript - PullRequest
0 голосов
/ 14 января 2020

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

function performOrder() {
  var available, placedOrder;
  available = checkCountOnServer(order.item, order.count);
  if (!available) {
    showNotAvailableMessage(order);
    return;
  }
  placedOrder = checkPayment(order.item, order.count, order.paymentMethod);
  if (askUserForConfirmationWithDialog(placedOrder)) {
    return confirmOrder(placedOrder);
  }
}

Мой подход к этому был:

function performOrder() {
  checkCountOnServerC(order.item, order.count, showNotAvailableMessage(order));
  return checkPaymentC(order.item, order.count, askUserConfirmationWithDialogC(placedOrder, confirmOrder(placedOrder));
}

Можно предположить, что все методы, добавленные с C, изменены, чтобы принять обратный вызов в качестве продолжения.

Мои вопросы: являются ли оба фрагмента эквивалентными и подтверждают ли второй стиль передачи продолжения?

Заранее большое спасибо!

1 Ответ

1 голос
/ 14 января 2020

Ваш код будет выполняться checkCountOnServerC и checkPaymentC параллельно, независимо от статуса available. Следовательно, они не эквивалентны.

Правильное преобразование будет зависеть от стиля, который вы хотите использовать: node.js стандартный стиль обратного вызова, Promises, successCallback / errorCallback et c. Предполагая, что вы хотите использовать node.js стандартный стиль обратного вызова:

function performOrderC(callback){
    checkCountOnServerC(order.item, order.count, function(err, available){
        if (! available ) {
            showNotAvailableMessage(order));
            callback(new Error('Not available'));
            return;
        } 
        checkPaymentC(order.item, order.count, function(err, placedOrder){
            askUserConfirmationWithDialogC(placedOrder, function(){
                callback(null, confirmOrder(placedOrder)); // this is how you "return" results
           });
       });
    });
}

Node.js стандартный стиль обратного вызова использует первый аргумент обратных вызовов для передачи ошибок в стек. Но до node.js это не было универсально принято асинхронными функциями.

Если вышеприведенное выглядит немного плотным (иногда его называют callback-адом), вы всегда можете изменить его, чтобы не использовать анонимные функции:

function checkPaymentHandler (callback) {
    return function (err, placedOrder){
        askUserConfirmationWithDialogC(placedOrder, function(){
            callback(null, confirmOrder(placedOrder)); // this is how you "return" results
        });
    });
}

function checkCountHandler (callback) {
    return function (err, available) {
        if (! available ) {
            showNotAvailableMessage(order));
            callback(new Error('Not available'));
            return;
        } 
        checkPaymentC(order.item, order.count, checkPaymentHandler(callback));
    }
}

function performOrderC(callback){
    checkCountOnServerC(order.item, order.count, checkCountHandler(callback));
}
...