我正在使用Typescript在Cordova中制作Android应用程序,并将其与Webpack捆绑在一起。我不太了解如何在Javascript中执行异步任务。我看过几个关于回调和承诺的教程,但它对我来说仍然很困惑,我无法将其调整到我的代码中。我不知道我的问题是来自我的代码本身,还是来自Typescript / Cordova / Webpack。
我创建了一个返回大对象的函数getAllSMS
,并且需要一些时间来执行。我知道该函数有效,因为如果我尝试在检查器的控制台中打印allSMS
变量,它首先是空的,然后填写为1秒。 (我认为检查员的行为很奇怪,但确实如此)。
我看到我可以使用promises执行异步任务,但是我有一些问题需要了解它是如何工作的。我看过几个教程,但我仍然不明白如何将它应用到我的代码中。
由于
[编辑]:这是我的getAllSMS函数转换为promise:
public getAllSMS() {
return new Promise(//return a promise
(resolve,reject)=>{
if (SMS) {
SMS.listSMS(this.filters, function (data) {
resolve(data);//added this, resolve promise
}, function (err) {
console.log('error list sms: ' + err);
reject(err);//added this reject promise
});
}else{
resolve([]);//added this, resolving to empty array?
}
}
).then(
data=>{
let contacts = {};
for (let key in data) {
if ((data[key].address).length > 7 && (data[key].address).match("[0-9]+")) {
let date = SMSManager.convertUnixDate(data[key].date); // on converti le format de date de listSMS
if (contacts.hasOwnProperty(data[key].address)) {
Object.defineProperty(contacts[data[key].address], data[key]._id, {
value: {
"body": data[key].body,
"date": date
}
});
} else {
let myid = String(data[key]._id);
Object.defineProperty(contacts, data[key].address, {
value: {
"000": {
"body": data[key].body,
"date": date
}
}
});
}
}
}
return contacts;
}
);
}
编辑2:我这样调用我的函数,但我的for循环仍未执行,尽管我的变量似乎已正确加载。
sms.getAllSMS().then( allSMS => {
console.log('allSMS');
console.log(allSMS);
console.log('then is readed'); // this is readed
for (let key in allSMS) {
console.log(allSMS[key]); // this is not executed
}
}).catch(
error => console.warn("something is wrong")
);
这是控制台的屏幕截图(控制台中的'Object'是allSMS)。在“对象”旁边有一个小小的“我”,上面写着:“下面的价值刚刚被评估了”。
答案 0 :(得分:1)
我怀疑sms.getAllSMS会返回一个承诺,因此您可以尝试以下操作:
sms.getAllSMS()
.then(
allSMS => {
for (let key in allSMS) {
console.log(allSMS[key]);
}
}
)
.catch(
error=>console.warn("something went wrong, error is:",error)
)
你的getAllSMS不会返回任何内容,请确保它返回一个承诺:
public getAllSMS(): object {
return new Promise(//return a promise
(resolve,reject)=>{
if (SMS) {
SMS.listSMS(this.filters, function (data) {
resolve(data);//added this, resolve promise
}, function (err) {
console.log('error list sms: ' + err);
reject(err);//added this reject promise
});
}else{
resolve([]);//added this, resolving to empty array?
}
}
).then(
data=>{
let contacts = {};
data.forEach(
item=>{
if ((item.address).length > 7 && (item.address).match("[0-9]+")) {
let date = SMSManager.convertUnixDate(item.date); // on converti le format de date de listSMS
if (contacts.hasOwnProperty(item.address)) {
Object.defineProperty(contacts[item.address], item._id, {
value: {
"body": item.body,
"date": date
}
});
} else {
Object.defineProperty(contacts, item.address, {
value: {
"000": {
"body": item.body,
"date": date
}
}
});
}
};
}
);
return contacts;
}
);
}
答案 1 :(得分:1)
你现在通过使用promises修复了异步问题,看起来很好。
for
循环没有枚举你的属性的问题是Object.defineProperty
(默认情况下)创建了不可枚举的属性。改为使用简单的作业:
let contacts = {};
for (const key in data) {
const address = data[key].address;
if (address.length > 7 && address.match("[0-9]+")) {
const date = SMSManager.convertUnixDate(data[key].date); // on converti le format de date de listSMS
const myid = String(data[key]._id);
if (address in contacts) {
contacts[address][myid] = {
"body": data[key].body,
"date": date
};
} else {
contacts[address] = {
"000": {
"body": data[key].body,
"date": date
}
}
}
}
}
return contacts;