2016-06-23 2 views
2

Мне нужно написать функцию, которая возвращает обещание, где сначала я вызываю синхронную функцию A(), которая возвращает некоторый результат. Затем верните функцию B (результат), где B - это обетование, которое принимает результат A(). Если какая-либо из функций не работает, я хочу, чтобы одна и та же функция ошибки C (ошибка) вызывалась, где C является обещанием. Каков наилучший способ написать это. Это то, что я имею, но думаю, что есть очевидный способ мне не хватаетПопробуйте и поймайте обещание

function() { 
    try { 
     var result = A(); 
     return B(result) 
      .catch(function(error) { 
       return C(error); 
      }); 
    } 
    catch(error) { 
     return C(error); 
    } 
} 

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

A() выдает ошибку, а не возвращает код ошибки.

+0

Вы знаете разницу между попыткой/уловкой и функцией улова Promise? Вы на самом деле пытаетесь обрабатывать исключения/ошибки, как это делает try/catch, или пытаетесь ли вы что-то делать, если обещание разрешает/отклоняет как улов, а затем выполняет функции Promise? – AUsr19532

+0

Когда вы говорите, что любая функция не работает, что это значит для 'A()'? Возвращает ли 'A' код ошибки, который указывает на отказ? Вызывает ли это исключение? Какой тип сбоя вы пытаетесь обнаружить? Пожалуйста, будьте более конкретными, чтобы мы могли предложить лучший ответ. Кроме того, вы говорите, что вы всегда вызываете 'C (error)', но C - это обещание. Это утверждение имеет смысл. Вы не выполняете такое обещание. Что именно вы подразумеваете под этим. Вы имеете в виду, что 'C' - это функция, которую вы хотите вызвать, если есть ошибка? – jfriend00

+0

Я имел в виду, что C - это функция, которая возвращает обещание. – user2802557

ответ

1

Вы не можете сказать, как именно A() терпит неудачу. Он может либо бросить, либо вернуть результат ошибки. Я покажу схему для обоих. Ключом к сочетанию синхронизации и асинхронного вызова всегда является обещание. Это даст вам согласованный интерфейс для вызывающего абонента независимо от того, как функция будет успешной или не удастся.

Если вы только беспокоит A() бросает исключение, и он не возвращает код ошибки, то вы можете сделать это:

function someFunction() { 
    try { 
     var result = A(); 
     return B(result); 
    } catch(err) { 
     return Promise.reject(err); 
    } 
} 

someFunction().then(function(result) { 
    // code here to process the final result 
}).catch(C); 

Если у вас также есть случай, когда A() может возвращать код ошибки , то вы можете сделать это:

function someFunction() { 
    try { 
     var result = A(); 
     // check for error value 
     if (result < 0) { 
      throw result; 
     } 
     return B(result); 
    } catch(err) { 
     return Promise.resolve(err); 
    } 
} 

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


Bluebird promise library имеет вспомогательную функцию для этого конкретного обстоятельства, называемого Promise.method. Утилита Promise.method() заключается в том, что она автоматически обертывает вашу функцию в обработчике try/catch, и если есть какие-либо синхронные исключения, которые они выбрасывают, она автоматически превращает их в возврат отклоненного обещания. Вы можете использовать его вот так:

var someFunction = Promise.method(function() { 
    var result = A(); 
    // check for error condition 
    if (result < 0) { 
     throw result; 
    } 
    return B(result); 
}); 

someFunction().then(function(result) { 
    // code here to process the final result 
}).catch(C); 
2

Я предполагаю, что и A, и B могут ошибаться здесь. Использование стандартного API это может выглядеть следующим образом:

function() { 
    return new Promise((resolve, reject) => { 
    try { 
     resolve(A()); 
    } catch (error) { 
     reject(error); 
    } 
    }) 
    .then(B) 
    .catch(C); 
} 

Это вернет обещание, что это либо разрешенное с выходом B или выходом C, если это обеспечивает запасной вариант. Вы также можете рассмотреть возможность обработки любых ошибок вне этой функции, если это имеет смысл для вашего варианта использования.

При использовании Bluebird это также должно быть возможно:

function() { 
    return Promise.method(A)().then(B).catch(C) 
} 
+0

Я тоже думал об этом, но разве неплохо было бы создать новое обещание? – user2802557

+0

Не совсем. В этом случае это необходимо, так как нам нужно поймать потенциальное исключение, созданное 'A'. – pablochan

+0

Как насчет случая, когда 'A()' не выбрасывает, а возвращает значение ошибки? – jfriend00

0

Я думаю, что хорошим способом сделать это было бы использование обещаний для синхронной функции. Он поддерживает его в рамках функции, особенно если вы хотите что-то ответить на успех, как псевдо-обещание. Но ключ заключается в том, что вы будете использовать немедленно разрешенное обещание. Взгляните на это blog post on ES6 Promises.

// an immediately resolved promise 
var a = Promise.resolve(A()); 

если вы уже создали обещание и определили C следующим образом:

var B = new Promise(function(resolve, reject) { 
    if (a) { 
     resolve('success'); // fulfilled successfully 
    } 
    else { 
     C('rejected'); // error, rejected 
    } 
}) 
.then((result) => {console.log('made it!');}) 
.catch((result) => {C('rejected');}); 

var C = (err)=>{console.log('error: ' + err); return err;} 

этот код должен делать то, что вы хотите:

a.then((result) => B(result)); 

^эта последняя строка является наиболее важно, поскольку он использует вывод для A для вызова B

+1

Promise.resolve (A()) не будет работать, если A() выдает ошибку – user2802557

Смежные вопросы