循环中的承诺:打字稿+角化+索引db

时间:2023-01-06 19:41:24

I'm working on a data synchronization service that is pulling down data from a web service and then storing it in IndexedDB.

我正在开发一个数据同步服务,它从web服务中提取数据,然后将其存储在IndexedDB中。

I'm doing something like this in my TypeScript Angular Service:

我正在我的打字稿角服务中做这样的事情:

this.http
    .post(postUrl, postData)
    .success((data: any, status, headers, config) => {

         console.log("post success");
         console.log("results:");
         console.log(data);

         var records = data.Records;
         var promiseStack = [];

         for (var i = 0; i < records.length; i++) {

             var element = records[i];
             var key = this.dataService.getKeyFromElement(objectStoreConfig, element);

             console.log("key: " + key);

             this.dataService.keyExists(objectStoreConfig, key).then((update) => {

                 if(update){
                     // TODO: put
                     promiseStack.push(true);
                 } else {
                     console.log("using dataService to add to objectStore...");
                     console.log("adding: " + key);
                     this.dataService.add(element, objectStoreConfig).then((result) => {
                         promiseStack.push(result);
                     });
                 }
             });

         }

         this.q.all(promiseStack).then((result) => {
             console.log("done adding/updating all.");
             deferred.resolve(result);
         });
    })
    .error((data, status, headers, config) => {
    });

I am getting a post success in the console, along with each returned record key that I anticipate. The trouble is with the asynchronous calls to my DataService. The this.dataService.add function is what actually creates a transaction and adds records to IndexedDb.

我正在控制台获得一个post成功,以及我预期的每个返回记录键。问题是对我的DataService的异步调用。this.dataService。add function实际上创建事务并向IndexedDb添加记录。

The output in my console (and in the state of IndexedDB - has just one record with a key of 188) indicates that this code sample only calls the add function on my DataService for the last element in records.

控制台中的输出(在IndexedDB的状态中只有一个记录,它的键值为188)表明,这个代码示例只调用记录中最后一个元素的数据错误上的add函数。

Console output:

控制台输出:

post success
results:
Object
key: 78 
key: 194
key: 188
done adding/updating all. 
using dataService to add to objectStore...
adding: 188
using dataService to add to objectStore...
adding: 188
using dataService to add to objectStore...
adding: 188  

How can I structure my code differently to make the for loop "wait" for each asynchronous call to be done?

如何以不同的方式构造代码,使for循环“等待”每一个异步调用完成?

1 个解决方案

#1


3  

Approach 1 (only works if you are targeting ES6)

方法1(仅适用于针对ES6的情况)

if you are using TypeScript 1.5 you can just use let instead of var to declare your element and key variables:

如果您使用的是TypeScript 1.5,您可以使用let而不是var来声明您的元素和关键变量:

let element = records[i];
let key = this.dataService.getKeyFromElement(objectStoreConfig, element);

The problem is that element and key are on the scope of the function not the for loop so every time the for loop iterates it is just replacing element and key variables instead of creating new variables. If you use let then the variables will be on the scope of the for loop.

问题是元素和键位于函数的范围内,而不是for循环,所以每次for循环迭代时,它只是替换元素和关键变量,而不是创建新的变量。如果使用let,则变量将位于for循环的范围内。

See What's-new-in-TypeScript for more details.

有关更多细节,请参见“打字稿”。

Approach 2

方法2

Alternatively you could also use Array.forEach instead of a for loop as that would also fix the scoping problem:

或者你也可以使用数组。forEach而不是for循环,这也可以解决范围问题:

records.forEach(function(element) {
    //...
});

#1


3  

Approach 1 (only works if you are targeting ES6)

方法1(仅适用于针对ES6的情况)

if you are using TypeScript 1.5 you can just use let instead of var to declare your element and key variables:

如果您使用的是TypeScript 1.5,您可以使用let而不是var来声明您的元素和关键变量:

let element = records[i];
let key = this.dataService.getKeyFromElement(objectStoreConfig, element);

The problem is that element and key are on the scope of the function not the for loop so every time the for loop iterates it is just replacing element and key variables instead of creating new variables. If you use let then the variables will be on the scope of the for loop.

问题是元素和键位于函数的范围内,而不是for循环,所以每次for循环迭代时,它只是替换元素和关键变量,而不是创建新的变量。如果使用let,则变量将位于for循环的范围内。

See What's-new-in-TypeScript for more details.

有关更多细节,请参见“打字稿”。

Approach 2

方法2

Alternatively you could also use Array.forEach instead of a for loop as that would also fix the scoping problem:

或者你也可以使用数组。forEach而不是for循环,这也可以解决范围问题:

records.forEach(function(element) {
    //...
});