【发布时间】:2018-09-28 11:38:32
【问题描述】:
我正在 Cordova 中使用 Typescript 为 Android 制作应用程序,并与 Webpack 捆绑。我不太了解如何在 Javascript 中执行异步任务。我看到了几个关于回调和承诺的教程,但对我来说仍然很困惑,我无法将它调整到我的代码中。我不知道我的问题是来自我的代码本身,还是来自 Typescript/Cordova/Webpack。
我创建了一个函数getAllSMS,它返回一个大对象,并且需要一些时间来执行。我知道该函数有效,因为如果我尝试在检查员的控制台中打印 allSMS 变量,它首先是空的,然后像 1 秒一样填充。 (我认为检查员的行为很奇怪,但确实如此)。
我看到我可以使用 Promise 执行异步任务,但我在理解它的工作原理方面遇到了一些问题。我看过几个教程,但我仍然不明白如何将它应用到我的代码中。
谢谢
[编辑]:这是我的 getAllSMS 函数转换为承诺:
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 in 循环仍未执行,尽管我的变量似乎已正确加载。
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")
);
这是控制台的屏幕截图(控制台中的“对象”是 allSMS)。在“对象”旁边有一个小“i”,上面写着:“下面的值刚刚被评估”。
【问题讨论】:
-
您需要向我们展示
getAllSMS中的代码。里面有些东西需要时间,这就是需要被包装在承诺中的东西。如果您拥有的let allSMS = sms.getAllSMS();不起作用,则在调用周围添加一些承诺不会改变有关该功能不起作用的任何内容。 -
见mdn doc for
then(),它有2个参数。另请参阅Promise.prototype.catch()。resolve()通常不将函数作为参数,您可能希望将那里的代码放入then()。看看一些例子。 -
在函数 sms.getAllSMS() 中返回新的 promise 并在 then() 中编写函数 getAllSMS
-
更新的答案,您的 getAllSMS 正在返回一个对象,该对象将来可能会或可能不会变异为有价值的东西。相反,您应该返回一个承诺,以便您知道数据何时可用以及是否可用(无错误)。
-
@Bergi 是的,我误解了如何使用承诺,这就是为什么我试图将它“围绕”该功能。但我知道该函数有效,因为如果我对应该在函数内部返回的变量
contact执行console.log,它就可以工作。如果我尝试在 then 函数中 console.log 它:sms.getAllSMS().then( allSMS => { console.log(allSMS);},它也可以工作。但是for in循环after仍然没有执行。
标签: javascript cordova typescript asynchronous promise