展平同步角度承诺

时间:2016-05-02 21:00:13

标签: javascript angularjs typescript

如何同步运行一系列承诺,以便第二个承诺在第一个承诺完成之前不执行?在这里,我正在加载三个数据块,每个客户端长10个,然后加载其余的数据。这里的想法是继续显示前N个客户端,其余客户端正在加载。

我不想要的是必须明确说出processChunk1()。然后(()=> processChunk2())等,就像我在下面一样。我希望它在循环中处理块,直到没有剩余的客户端为止。任何帮助将不胜感激!

loadPerformanceDtos(): ng.IPromise<{}> {
    var deferred = this.$q.defer();
    var clientList: any = [];

    $.extend(clientList, this.$location.search().client);

    // If the user only searched for one client, we need to turn it into an array
    if (!angular.isArray(clientList)) {
        clientList = [clientList];
    }

    var that = this;

    // Sort so we can chunk it
    var sortedClients: string[] = (<string[]>clientList).sort();
    const chunkSize: number = 10;

    // Reset page's data
    this.performanceDtoModels = [];

    // Set up three chunks to load in order
    var chunk1: string[] = sortedClients.splice(0, chunkSize);
    var chunk2: string[] = sortedClients.splice(0, chunkSize);
    var chunk3: string[] = sortedClients.splice(0, chunkSize);

    // I don't want to have to explicitly define the groups below, I want this to be in a loop
    processChunk(chunk1).then(() => {
        // Resolve the inital page's progress bar
        deferred.resolve();

        processChunk(chunk2).then(() => {
            processChunk(chunk3).then(() => {
                processChunk(sortedClients);
            });
        });
    });

    function processChunk(chunk: string[]) {
        var chunkDeferred = that.$q.defer();
        if (chunk.length === 0) {
            chunkDeferred.resolve();
        } else {
            that.performanceService.loadPerformanceData(chunk)
                .success((data: IPerformanceDtoModel[]) => {
                    data.forEach((item: IPerformanceDtoModel) => {
                        // Add the final item to the page
                        that.performanceDtoModels.push(item);
                    });

                    chunkDeferred.resolve();
                });
        }
        return chunkDeferred.promise;
    }

    return deferred.promise;
}

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法是使用递归函数,该函数在每个异步操作完成后使用原始列表的片段调用自身。下面是一个示例实现。请注意,var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheets()[0]; //Sheet1 is in Array[0] var range = sheet.getRange(1, 1, sheet.getLastRow()); function onOpen() { //add menu called Visibility onOpen ss.addMenu("Visibility", [{ name: "Show All Rows", functionName: "showAllRows" }, { name: "Hide All Empty Rows", functionName: "hideAllEmptyRows" } ] ); } function showAllRows(){ sheet.showRows(1,sheet.getLastRow()); } function hideAllEmptyRows(){ //get the values to those rows var values = range.getValues(); //go through every row for (var i=0; i<values.length; i++){ //if row value is equal to empty if(values[i][0] === ""){ //hide that row sheet.hideRows(i+1); } } } 在每次异步操作后调用自身。

此实现不考虑异步方法何时失败。它不包括任何知道所有块何时完成加载的方法。对于后者,您必须添加一些逻辑来确定最后一个块的加载时间。

processChunks