TypeScript - לולאת for סינכרונית עם הבטחות ופונקציות מרובות
סקירה בסיסית.
יש לי מערך נתונים שאני רוצה לעבור עליו עם משפט for.
אני לא רוצה להמשיך לפריט הבא בלולאת ה-for עד ששתי הפונקציות בפנים יסיימו. פונקציה 1 תלויה בהצלחת פונקציה 2, אם אחת מהן נכשלת אני רוצה שהלולאה תעצור.
הנה שתי הפונקציות שלי.
submitEntryPromise(entry): Promise < any > {
return new Promise((resolve, reject) => {
this.submitEntry(entry).take(1).subscribe(data => {
if (data) {
resolve(data);
}
}, (error: any) => {
console.log('rejected submitEntry' + JSON.stringify(error));
reject(false);
});
});
}
deleteEntryFromSqlLitePromise(rowid): Promise < any > {
return new Promise((resolve, reject) => {
this.deleteEntry(rowid).then(res => {
if (res) {
resolve(res);
} else {
reject(false);
}
}).catch((error: any) => {
console.log('reject delete' + JSON.stringify(error));
reject(false);
});
});
}
מערך הנתונים שלי (שהוחזר ממסד הנתונים המקומי של SQL Lite) נקרא savedEntries
ניסיתי משהו כזה.
for (let i = 0, p = Promise.resolve(); i < savedEntries.rows.length; i++) {
p = p.then(_ => this.wpservice.submitEntryPromise(
{
score: savedEntries.rows.item(i).score,
email: savedEntries.rows.item(i).email
}))
}
אבל אני לא בטוח איפה לקרוא לפונקציה שלי deleteEntryFromSqlLitePromise ואני לא בטוח אם אלו יבוצעו לפי הסדר?
בעיקרון אני עובר על רשומות שמורות במסד נתונים SQL לא מקוון, ומסנכרן אותן עם השרת שלי, כאשר השרת אומר שקיבל רשומה אני רוצה להסיר אותה מהמסד המקומי.
כל עצה תתקבל בברכה, אני כותב ב-TypeScript עבור הפרויקט שלי ב-Ionic.
תשובה #1
מכיוון שאתה משתמש ב-Typescript, כדאי ששקול להשתמש ב-async/await זה מאפשר לך לכתוב קוד אסינכרוני בצורה שנראית סינכרונית:
async deleteEntryFromSqlLitePromise(rowid): Promise<any> {
try {
let res = await this.deleteEntry(rowid);
return res || false;
} catch (error) {
console.log('reject delete' + JSON.stringify(error));
return false;
}
}
async deleteAll(savedEntries: { rows: { length: number, item(i: number): any } }) {
let rows = savedEntries.rows;
for (let i = 0; i < rows.length; i++) {
try {
let synced = await this.wpservice.submitEntryPromise(
{
score: rows.item(i).score,
email: rows.item(i).email
});
if (synced) {
let deleted = await this.wpservice.deleteEntryFromSqlLitePromise(rows.item(i).rowid)
if (!deleted) {
// decide whta to do if not deleted
}
} else {
// decide what to do if not synced
}
} catch (e) {
// Decide what to do with any errors
}
}
}
