如何从typescript中的静态参数数组中链接promise



我不知道如何迭代数组并向每个项发送一个链接的promise。我正试图在下面定义DBSchema.executeMigrations(详细信息请参见注释)。

假设migrations将随着时间的推移而增长。所以,现在只有3个args,但明年可能是100个。我需要这个来迭代。

export class DBConnection {
exec(query): Promise<any> {
let _this = this;
return new Promise((resolve) => {
_this.get().then((db) => {
db.executeSql(query, {}).then(
(result) => {
resolve(result);
},
(err) => {
console.log('Unable to execute query: ' + err.message);
}
);
});
});
}
}

export class DBSchema {
constructor(public db_connection: DBConnection){};
static migrations = [
"CREATE TABLE IF NOT EXISTS events(id INTEGER PRIMARY KEY NOT NULL, title STRING)",
"CREATE TABLE IF NOT EXISTS news(id INTEGER PRIMARY KEY NOT NULL, title STRING)",
"CREATE TABLE IF NOT EXISTS whatever(id INTEGER PRIMARY KEY NOT NULL, title STRING)"
];
executeMigrations(): any {
// send each migration to db_connection.exec
// do it in order
// return a promise that resolves when all of them are done
}
}

让promise按顺序运行和解析的一种简单方法是用Array.prototype.reduce()迭代它们。这样,您就可以用一个立即解析的promise开始迭代,并将promise的执行顺序与来自数组的下一个值链接起来。

您的exec()函数是用所谓的延迟反模式/显式承诺构建模式实现的,这被认为是一种糟糕的做法,应该避免。不需要创建新的promise,而应该从_this.get()返回一个。

重构函数以返回现有的promise会使其看起来像这个

exec(query): Promise<any> {
let _this = this;
return _this.get().then((db) => {
return db.executeSql(query, {})
.then((res) => { return res }) //not really necessary but to make it more clear
.catch((err) => {
console.log('Unable to execute query: ' + err.message);
}
);
});
}

通过使用Array.prototype.reduce(),您可以让所有的查询按顺序运行,并使用类似的功能相互等待

executeMigrations(): Promise<any> {
return DBSchema.migrations.reduce((previousValue: Promise<string>, currentValue: string): Promise<any> => {
return previousValue.then(() => {
return this.db_connection.exec(currentValue);
});
}, Promise.resolve());
}

当所有"内部"承诺都得到解决时,从executeMigrations()返回的承诺就会得到解决,这使得您可以很容易地使用常规.then()继续处理其他内容,就像executeMigrations().then(...)一样。

最新更新