循环内的承诺:TypeScript + Angular + IndexedDB
Promises within a loop: TypeScript + Angular + IndexedDB
我正在开发一项数据同步服务,该服务从 Web 服务中提取数据,然后将其存储在 IndexedDB 中。
我正在我的 TypeScript Angular 服务中做这样的事情:
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) => {
});
我在控制台中得到一个 post success
,以及我预期的每个返回的 record
key
。问题在于对我的 DataService
的异步调用。 this.dataService.add
函数实际上是创建事务并将记录添加到 IndexedDb。
我的控制台中的输出(在 IndexedDB 的状态下 - 只有一条记录的键为 188
)表明此代码示例 仅 调用了add
在我的 DataService
上为 records
.
中的最后一个元素运行
控制台输出:
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
如何以不同的方式构建我的代码,以便为每个要完成的异步调用创建 for 循环 "wait"?
方法 1(仅适用于针对 ES6 的情况)
如果您使用的是 TypeScript 1.5,您可以只使用 let
而不是 var
来声明您的元素和键变量:
let element = records[i];
let key = this.dataService.getKeyFromElement(objectStoreConfig, element);
问题是 element
和 key
在函数的范围内而不是 for 循环所以每次 for 循环迭代它只是替换 element
和 key
变量而不是创建新变量。如果您使用 let
那么变量将在 for 循环的范围内。
有关详细信息,请参阅 What's-new-in-TypeScript。
方法二
或者,您也可以使用 Array.forEach 而不是 for 循环,因为这也可以解决作用域问题:
records.forEach(function(element) {
//...
});
我正在开发一项数据同步服务,该服务从 Web 服务中提取数据,然后将其存储在 IndexedDB 中。
我正在我的 TypeScript Angular 服务中做这样的事情:
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) => {
});
我在控制台中得到一个 post success
,以及我预期的每个返回的 record
key
。问题在于对我的 DataService
的异步调用。 this.dataService.add
函数实际上是创建事务并将记录添加到 IndexedDb。
我的控制台中的输出(在 IndexedDB 的状态下 - 只有一条记录的键为 188
)表明此代码示例 仅 调用了add
在我的 DataService
上为 records
.
控制台输出:
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
如何以不同的方式构建我的代码,以便为每个要完成的异步调用创建 for 循环 "wait"?
方法 1(仅适用于针对 ES6 的情况)
如果您使用的是 TypeScript 1.5,您可以只使用 let
而不是 var
来声明您的元素和键变量:
let element = records[i];
let key = this.dataService.getKeyFromElement(objectStoreConfig, element);
问题是 element
和 key
在函数的范围内而不是 for 循环所以每次 for 循环迭代它只是替换 element
和 key
变量而不是创建新变量。如果您使用 let
那么变量将在 for 循环的范围内。
有关详细信息,请参阅 What's-new-in-TypeScript。
方法二
或者,您也可以使用 Array.forEach 而不是 for 循环,因为这也可以解决作用域问题:
records.forEach(function(element) {
//...
});