我正在研究以下Promise场景,并且我不明白为什么第二个然后条件没有在设置方法中受到影响。当这个代码在app.js中运行时,我看到initialize()在哪里被命中,并且它等待按预期进行数据库连接,但是一旦初始化达到了解决条件,就不会出现任何其他被调用的内容。我在catch中设置了断点,但从未调用过;也没有在设置方法中达到的捕获量。我希望在完成后立即调用initializeAppSettings。
我不知道这里有什么问题。我真的需要有人来审查并解释我在这个承诺方案中出错的地方吗?
setup = () => {
let p = new Promise(initialize)
.then(this.initializeAppSettings)
.then(() => {
this.appServer.listen(3000, () => {
console.log('Server started on port 3000 :)');
});
})
.catch((err: Error) => {
throw err;
});
}
export let initialize = (): Promise<Container> => {
let p = new Promise((reject, resolve) => {
var container = new Container();
initializeDBConnection(process.env.DB_HOST)
.then((dbClient: Repository.DbClient) => {
container.bind<DbClient>(TYPES.DbClient).toConstantValue(dbClient);
resolve(container);
})
.catch((err: Error) => {
reject(err);
});
});
return p;
}
this.initializeAppSettings = (container: Container): Promise<any> => {
/*
* This code is never called
*/
let p = new Promise((reject, resolve) => {
let server = new InversifyExpressServer(container);
server.setConfig((app) => {
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, "public")));
//configure pug
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");
//mount logger
app.use(methodOverride());
}).setErrorConfig((app) => {
if (process.env.NODE_ENV === "development") {
app.use(function (err: Error, req: express.Request, res: express.Response, next: express.NextFunction) {
else {
//res.status(500).send('An error occurred while processing your request.');
res.statusCode = 500;
return res.json({
errors: ['An error occurred while processing your request.']
});
}
}
});
this.appServer = server.build();
resolve();
});
return p;
}
答案 0 :(得分:1)
你在这里创造的外在承诺:
setup = () => {
let p = new Promise(initialize)
.then(this.initializeAppSettings)
.then(() => {
this.appServer.listen(3000, () => {
console.log('Server started on port 3000 :)');
});
})
.catch((err: Error) => {
throw err;
});
}
永远不会被解析,因此永远不会调用附加到它的.then()
处理程序。
这里有很多问题。我不认为我可以覆盖所有这些,但我会通过其中的一些。
首先,您要避免创建新承诺的承诺反模式来包装另一个承诺。你很简单,不需要这样做。因此,如果initialize()
是一个函数,它返回一个在它完成时解析的promise(这是代码中的另一个问题,但我们假设它已正确编写),那么你可以这样做:< / p>
setup = () => {
return initialize()
.then(this.initializeAppSettings.bind(this))
.then(() => {
this.appServer.listen(3000, () => {
console.log('Server started on port 3000 :)');
});
});
}
现在,因为完成this.appServer.listen()
没有以任何方式连接到您的承诺链,它会在您需要时启动,但它的完成将无法与您的承诺相协调(只要它想要,它就会完成)。你可以&#34; promisify&#34;它,如果你想将它链接到你的承诺链。
另请注意,我已将this.initializeAppSettings
更改为this.initializeAppSettings.bind(this)
,以便在this
处理程序中保留.then()
的值。
现在,只有当initialize()
返回在适当时间解析的承诺时,上述方法才能正常工作。你确实试图这样做,但是你再一次用诺言反模式来实现它,你就是这样。而不是创建自己的承诺,而应该返回你已经拥有的承诺:
export let initialize = (): Promise<Container> => {
var container = new Container();
return initializeDBConnection(process.env.DB_HOST)
.then((dbClient: Repository.DbClient) => {
container.bind<DbClient>(TYPES.DbClient).toConstantValue(dbClient);
// make resolved value be the container
return container;
});
}