javascript - 为什么我的 Promise 链不能以这种嵌套方式工作?

标签 javascript angularjs promise angular-promise

我想在 Promise 链中链接 4 个函数,如下所示:

函数1 -> 函数2 -> 函数3 -> 函数4

我的 promise 链

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: enter image description here

^ 注意我从未见过此日志:

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);
    });
});

但是我从未在 displayViewHeaderTags.then 函数中看到 console.log <小时/>

这是我的 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 次,在获取数据完成后,它将填满并数组,然后调用 defffered.resolve 。然后返回它 return deferred.promise;

那为什么我从来没有看到这个日志呢? console.log('viewHeader.vh.displayViewHeaderTags 完成!');

最佳答案

你的 i 永远不会与长度相同,因为 i 变量从零开始(数组索引从零开始)。这意味着如果你有一个长度 = 2 的数组,你的 i 值将分别为 0 和 1。它永远不会等于零。基本上,您希望条件是:

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

无论如何,使用defer()code smell .

更优雅的方法是使用 $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 );

关于javascript - 为什么我的 Promise 链不能以这种嵌套方式工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33444624/

相关文章:

javascript - Promise.all() 返回未定义的 Promise <Pending> 数组,尽管类似的解决方案返回成功的替代方案

javascript - Angular 6 解析始终未定义

javascript - Jquery ajax错误导致无限循环

javascript - AngularJS ng-repeat - jquery Datepicker 在 ng-repeat 中不工作

javascript - 异步等待 promise

Javascript ES6 promise 在类函数内

javascript - 使用 POST 的 NodeJS 快速身份验证返回错误 发送后无法设置 header

javascript - jQuery 滚动功能不起作用

javascript - 避免在每次迭代 Javascript AngularJS 中覆盖值

javascript - 删除之前淡出列表中的项目