JavaScript 循环中的异步调用 - Apache Cordova
Async call in JavaScript Loop - Apache Cordova
我有一组联系人从我的数据库返回,我需要检查它们是否在设备上,然后 save/update 设备上的联系人。问题是 cordova 中的 navigator.contacts.find(fields, findSuccess, findError, options);
调用是异步的。
我遇到的问题是 for 循环将使用新数据在 onSuccess
被触发之前进行下一次迭代。这意味着它将尝试 save/update 使用相同的数据两次或根本没有数据。
$scope.syncContacts = function () {
var table = AzureService.getTable('contact');
table.read().done(function (results) {
console.log("Results: ", results);
for (var i = 0; i < results.length; i++) {
//create a contact object to save or update
var emails = [];
var phoneNumbers = [];
var name = new ContactName();
var contactToUpdate = navigator.contacts.create();
contactToUpdate.note = results[i].id;
name.givenName = results[i].firstname;
name.familyName = results[i].lastname;
phoneNumbers[0] = new ContactField('mobile', results[i].mobilephone, true);
phoneNumbers[1] = new ContactField('home', results[i].homephone, false);
emails[0] = new ContactField('work', results[i].email, true);
contactToUpdate.name = name;
contactToUpdate.phoneNumbers = phoneNumbers;
contactToUpdate.emails = emails;
//Search for the contact on the device
var options = new ContactFindOptions();
options.filter = results[i].id;
options.multiple = false;
var fields = ["*"];
navigator.contacts.find(fields, foundSuccess, foundError, options);
function foundSuccess(contact) {
if (contact.length > 0) {
contactToUpdate.id = contact[0].id;
contactToUpdate.rawId = contact[0].rawId;
contactToUpdate.phoneNumbers[0].id = contact[0].phoneNumbers[0].id;
contactToUpdate.phoneNumbers[1].id = contact[0].phoneNumbers[1].id;
contactToUpdate.emails[0].id = contact[0].emails[0].id;
console.log('about to save this', contactToUpdate);
contactToUpdate.save(upSuccess, upError);
function upSuccess() {
console.log('updated a contact!');
}
function upError(ContactError) {
console.log('error updating a contact!');
}
}
else {
//The contact does not exist on the device. Just save it.
console.log('non existent contact: ', contactToUpdate);
contactToUpdate.save(saveSuccess, SaveError);
function saveSuccess() {
console.log('saved a contact!');
}
function SaveError() {
console.log('error saving a contact!');
}
}
}
function foundError() {
alert('Contact search failed: Undeleted Contact Search');
}
}
}
});
};
我的问题是,我该如何处理?我的想法是可能使用 forEach 因为返回的是一个数组。
这会确保只使用正确的数据,还是我需要完全采用另一种方法?
更改为 forEach 循环解决了这个问题
我有一组联系人从我的数据库返回,我需要检查它们是否在设备上,然后 save/update 设备上的联系人。问题是 cordova 中的 navigator.contacts.find(fields, findSuccess, findError, options);
调用是异步的。
我遇到的问题是 for 循环将使用新数据在 onSuccess
被触发之前进行下一次迭代。这意味着它将尝试 save/update 使用相同的数据两次或根本没有数据。
$scope.syncContacts = function () {
var table = AzureService.getTable('contact');
table.read().done(function (results) {
console.log("Results: ", results);
for (var i = 0; i < results.length; i++) {
//create a contact object to save or update
var emails = [];
var phoneNumbers = [];
var name = new ContactName();
var contactToUpdate = navigator.contacts.create();
contactToUpdate.note = results[i].id;
name.givenName = results[i].firstname;
name.familyName = results[i].lastname;
phoneNumbers[0] = new ContactField('mobile', results[i].mobilephone, true);
phoneNumbers[1] = new ContactField('home', results[i].homephone, false);
emails[0] = new ContactField('work', results[i].email, true);
contactToUpdate.name = name;
contactToUpdate.phoneNumbers = phoneNumbers;
contactToUpdate.emails = emails;
//Search for the contact on the device
var options = new ContactFindOptions();
options.filter = results[i].id;
options.multiple = false;
var fields = ["*"];
navigator.contacts.find(fields, foundSuccess, foundError, options);
function foundSuccess(contact) {
if (contact.length > 0) {
contactToUpdate.id = contact[0].id;
contactToUpdate.rawId = contact[0].rawId;
contactToUpdate.phoneNumbers[0].id = contact[0].phoneNumbers[0].id;
contactToUpdate.phoneNumbers[1].id = contact[0].phoneNumbers[1].id;
contactToUpdate.emails[0].id = contact[0].emails[0].id;
console.log('about to save this', contactToUpdate);
contactToUpdate.save(upSuccess, upError);
function upSuccess() {
console.log('updated a contact!');
}
function upError(ContactError) {
console.log('error updating a contact!');
}
}
else {
//The contact does not exist on the device. Just save it.
console.log('non existent contact: ', contactToUpdate);
contactToUpdate.save(saveSuccess, SaveError);
function saveSuccess() {
console.log('saved a contact!');
}
function SaveError() {
console.log('error saving a contact!');
}
}
}
function foundError() {
alert('Contact search failed: Undeleted Contact Search');
}
}
}
});
};
我的问题是,我该如何处理?我的想法是可能使用 forEach 因为返回的是一个数组。
这会确保只使用正确的数据,还是我需要完全采用另一种方法?
更改为 forEach 循环解决了这个问题