2016-08-31 2 views
2

В приведенном ниже коде я звоню Pouch.sync(), к которому я связываюсь deleteLocal(). Pouch.sync() выполняет localDb.sync(), который не возвращает обещание, но я могу подключить обработчик события .on() для обработки ошибок.

Я попытался сыграть с $ q.when и $ q.reject, но я не могу помешать deleteLocal() от обстрела, если синхронизация завершилась неудачно, и onError() никогда не выполняет (либо в качестве обратного вызова ошибки, либо в catch).

// Controller 
function _onSyncClick() { 
    return Pouch.sync() 
     .then(deleteLocal, onError); // I do not want deleteLocal() to execute if Pouch.sync() fails 
     .catch(onError); 
} 


// Pouch service 
function sync() { 
    return 
     localDb.sync(remoteDb) 
      .on('error', function (err) { 
       return $q.reject('Sync error.'); 
      }); 
} 

ответ

0

.synch() использует обратный вызов API, вы можете использовать $q.when и $q.reject к promisify его.

return localDB.sync(remoteDB).on('complete', function() { 
    return $q.when("done!"); 
}).on('error', function (err) { 
    return $q.reject(err); 
}); 

Кроме того, когда цепочки обещаний, вы должны убедиться, что вы либо throw ошибку или вернуть отклоненный обещание, в противном случае вы будете вызывать обработчик resolve/success.

так или .on('error', errorHandler) не побежал, как вы, хотя бы или Pouch.sync() не вызывал вашу функцию.

+0

спасибо. Я вернул '$ q.reject()' в обработчик ошибок, но цепочечная функция все еще выполняется. Используя контрольные точки, я подтвердил, что обработчик ошибок действительно достигнут, но 'deleteLocal()' все еще выполняется после ошибки. Почему '$ q.reject()' не нарушает цепочку? – devthorne

+0

Я случайно использовал '.when 'второй раз, я отредактировал свой ответ – svarog

+0

', но deleteLocal() все еще выполняется после ошибки. ', Я предполагаю, что функция была вызвана' localDB.sync'. вы не можете запустить оба успеха и отклонить обработчики обещания – svarog

0

Сначала ваш then() не следует звонить deleteLocal с onError.

Далее, на основе документации по угловому устройству: Если вы «поймаете» ошибку с помощью обратного вызова с ошибкой обещания, и вы хотите переслать ошибку на обещание, полученное из текущего обещания, вам нужно «перебросить» ошибку на возвращая отказ, построенный через $q.reject

Таким образом, вы рассматриваете событие обратного вызова как обещание, и, возможно, именно поэтому не забрасывает отклонение.

Правильно, я думаю, что это Promisify события обратного вызова от sync() с использованием конструктора $q.

// Controller 
function _onSyncClick() { 
    return Pouch.sync().then(deleteLocal).catch(onError); 
} 

// Pouch Service, method sync 
function sync() { 
    return $q(function (resolve, reject) { 
    localDb.sync(remoteDb, { 
     // options 
    }).on('complete', function (info) { 
     resolve(info); 
    }).on('error', function (err) { 
     reject(err); 
    }); 
    }); 
} 

Просто упоминает, $q.when оборачивает объект, который может быть значением или (третья сторона) тогда в состоянии обещания в $ д обещание не использовать его в качестве решимости, использовать его, чтобы обернуть PouchDB обещает.