Почему моя цепочка обещаний не работает таким образом?

0

Я хочу связать 4 функции в цепочке Promise следующим образом:

function1 → function2 → function3 → function4

Моя цепочка обещаний

if ($location.$$url !== "/dashboard") {
    vm.customURL = true;
    // (1) Set root vars & Rebuild tickerTagsContainer:
    var promise = TagFactory.buildUrlObject($location.$$url).then(function() {
        console.log('TagFactory.buildUrlObject PROMISE returned');
    }).then(function() {
        console.log('(2) Re-display tags in viewHeader');
        // (2) Re-display tags in viewHeader:
        viewHeader = ScopeFactory.getScope('viewHeader');
        viewHeader.vh.displayViewHeaderTags().then(function() {
            console.log('viewHeader.vh.displayViewHeaderTags FINISHED!');
        });
    }).then(function() {
        // (3) Reselect timeSpan:
        console.log('(3) Reselect timeSpan');
        viewHeader.vh.toggleTimeSpan(vm.timeSpan);
        // (4) Refresh URL:
        console.log('(4) Refresh URL');
        ViewFactory.remakeViewObject($location.$$url);
    });
}

В результате console.logs: Изображение 174551

^ Примечание. Я никогда не вижу этот журнал:

viewHeader.vh.displayViewHeaderTags().then(function() {
    console.log('viewHeader.vh.displayViewHeaderTags FINISHED!');
});

В идеале я хочу разместить в нем свою (3) функцию, а затем привязать ее (4) так:

viewHeader.vh.displayViewHeaderTags().then(function() {
    console.log('viewHeader.vh.displayViewHeaderTags FINISHED!');
    console.log('(3) Reselect timeSpan');
    viewHeader.vh.toggleTimeSpan(vm.timeSpan).then(function() {
        console.log('(4) Refresh URL');
        ViewFactory.remakeViewObject($location.$$url);
    });
});

Однако я никогда не вижу console.log из функции .then для displayViewHeaderTags


Вот как выглядит мой displayViewHeaderTags:

function displayViewHeaderTags() {
    vm.viewTickerTags = [];
    vm.viewTickerTags = TagFactory.retrieveTickerTags('all');

    var deferred = $q.defer();
    var tikObjs  = vm.viewTickerTags.map(function(el) { return el.ticker; });
    var tagObjs  = vm.viewTickerTags.map(function(el) { return el.tags; });
    var tags     = _.flatten(tagObjs);

    // forEach loops up to 3 times:
    tags.forEach(function(tag, i) {
        vm.viewTags = [];
        ApiFactory.getTagDataSilm(tag.term_id).then(function(data) {
            vm.viewTags.push(data.data.ticker_tag);
            if (i === tags.length) {
                deferred.resolve();
            }
        });
    });

    return deferred.promise;
}

Внутри моей функции displayViewHeaderTags я нажимаю цикл, который будет работать до 3-х раз, после того, как он будет получать данные, он заполнит и массив затем deffered.resolve. затем возвращает его return deferred.promise;

Так почему я никогда не вижу этот журнал? console.log('viewHeader.vh.displayViewHeaderTags FINISHED!');

Теги:
promise
angular-promise

2 ответа

1
Лучший ответ

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

if ($location.$$url !== "/dashboard") {
    vm.customURL = true;
    // (1) Set root vars & Rebuild tickerTagsContainer:
    var promise = TagFactory.buildUrlObject($location.$$url).then(function() {
        console.log('TagFactory.buildUrlObject PROMISE returned');
    }).then(function() {
        console.log('(2) Re-display tags in viewHeader');
        // (2) Re-display tags in viewHeader:
        viewHeader = ScopeFactory.getScope('viewHeader');
        return viewHeader.vh.displayViewHeaderTags().then(function() {
            console.log('viewHeader.vh.displayViewHeaderTags FINISHED!');
        });
    }).then(function() {
        // (3) Reselect timeSpan:
        console.log('(3) Reselect timeSpan');
        return viewHeader.vh.toggleTimeSpan(vm.timeSpan);
    }).then(function() {
        // (4) Refresh URL:
        console.log('(4) Refresh URL');
        return ViewFactory.remakeViewObject($location.$$url);
    }).catch(function(error) {
        console.log('Something failed', error);
    });
}

В displayViewHeaderTags вы можете использовать $q.all, так что отклонения обрабатываются для вас:

// forEach loops up to 3 times:
vm.viewTags = [];

return $q.all(_.map(tags, function(tag) {
    return ApiFactory.getTagDataSilm(tag.term_id).then(function(data) {
        vm.viewTags.push(data.data.ticker_tag);
    });
}));
  • 0
    ? Не следуя, я возвращаю Promise из buildUrlObject, вот так он может продолжить цепочку. В displayViewHeaderTags я также возвращаю Promise таким же образом ... однако он не продолжается в своей вложенной цепочке. В моем вызове ApiFactory нет ошибки, но я добавил улов.
  • 0
    @LeonGaban - код и изучение ANID видит ВСЕ другие места , которые они добавили return заявления для возврата обещаний внутри .then() обработчиков.
Показать ещё 2 комментария
2

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

vm.viewTags.push(data.data.ticker_tag);
if (i + 1 === tags.length) {
    deferred.resolve();
}

Во всяком случае, использование defer() является запахом кода.

Более элегантный способ сделать это будет использовать $ q.all

var allPromises = [];
var promise;
tags.forEach(function(tag) {
    vm.viewTags = [];
    promise = ApiFactory.getTagDataSilm(tag.term_id).then(function(data) {
        vm.viewTags.push(data.data.ticker_tag);
    });

    // Create an array of promises, one promise for each request
    allPromises.push( promise );
});

// Return a new promise that will only be resolved 
// when all the promises of the array 'allPromises' are resolved,
// or is rejected when one of them is.
return $q.all( allPromises );
  • 0
    AH! Спасибо, это была моя проблема ... Теперь я вижу журнал, который я пытался перехватить, и могу продолжить цепочку вложенных обещаний.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню