node.js:Promse出现了一个奇怪的问题';那就不打电话了
我正在处理以下Promise场景,不理解为什么第二个then条件在设置方法中没有被击中。当这段代码在app.js中运行时,我看到initialize()在何处被命中,它等待数据库连接按预期进行,但一旦initialize中达到解析条件,就不会调用任何其他内容。我在catch中设置了断点,但从未调用过断点;在设置方法中也没有达到捕获。我希望在完成后立即调用initializeAppSettings 我不明白这里出了什么问题。我真的需要有人来回顾和解释我在这个承诺场景中犯了什么错误node.js:Promse出现了一个奇怪的问题';那就不打电话了,node.js,typescript,es6-promise,Node.js,Typescript,Es6 Promise,我正在处理以下Promise场景,不理解为什么第二个then条件在设置方法中没有被击中。当这段代码在app.js中运行时,我看到initialize()在何处被命中,它等待数据库连接按预期进行,但一旦initialize中达到解析条件,就不会调用任何其他内容。我在catch中设置了断点,但从未调用过断点;在设置方法中也没有达到捕获。我希望在完成后立即调用initializeAppSettings 我不明白这里出了什么问题。我真的需要有人来回顾和解释我在这个承诺场景中犯了什么错误 setup =
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;
}
setup=()=>{
设p=新承诺(初始化)
。然后(此。初始化AppSettings)
.然后(()=>{
this.appServer.listen(3000,()=>{
log('服务器在端口3000上启动:);
});
})
.catch((错误:Error)=>{
犯错误;
});
}
导出让初始化=():承诺=>{
让p=新承诺((拒绝,解决)=>{
var container=新容器();
initializeDBConnection(process.env.DB_HOST)
.then((dbClient:Repository.dbClient)=>{
container.bind(TYPES.DbClient).toConstantValue(DbClient);
解决(集装箱);
})
.catch((错误:Error)=>{
拒绝(错误);
});
});
返回p;
}
this.initializeAppSettings=(容器:容器):Promise=>{
/*
*此代码从未被调用
*/
让p=新承诺((拒绝,解决)=>{
让服务器=新服务器(容器);
server.setConfig((应用)=>{
app.use(bodyParser.urlencoded({
扩展:正确
}));
use(bodyParser.json());
app.use(express.static(path.join(u dirname,“public”));
//配置哈巴狗
app.set(“视图”,path.join(uu dirname,“视图”);
应用程序集(“查看引擎”、“哈巴狗”);
//挂载记录器
使用(methodOverride());
}).setErrorConfig((应用)=>{
if(process.env.NODE_env==“开发”){
应用程序使用(函数(err:Error,req:express.Request,res:express.Response,next:express.NextFunction){
否则{
//res.status(500).send('处理您的请求时出错');
res.statusCode=500;
返回res.json({
错误:[“处理您的请求时出错”。]
});
}
}
});
this.appServer=server.build();
解决();
});
返回p;
}
您在此处创建的外部承诺:
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()
是一个函数,它返回一个承诺,并在完成时解决(这是代码中的另一个问题,但假设它编写正确),那么您可以执行以下操作:
setup = () => {
return initialize()
.then(this.initializeAppSettings.bind(this))
.then(() => {
this.appServer.listen(3000, () => {
console.log('Server started on port 3000 :)');
});
});
}
现在,由于完成this.appServer.listen()
没有以任何方式连接到您的承诺链,它将在您希望的时候开始,但它的完成将与您的承诺完全不协调(它只会在任何时候完成)。您可以“promisify”如果你想把它拴在你的承诺链上
还请注意,我已将this.initializeAppSettings
更改为this.initializeAppSettings.bind(this)
,以在处理程序中保留this
的值
现在,只有当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;
});
}
export-let-initialize=():Promise=>{
var container=新容器();
返回initializeDBConnection(process.env.DB_HOST)
.then((dbClient:Repository.dbClient)=>{
container.bind(TYPES.DbClient).toConstantValue(DbClient);
//将解析值设置为容器
返回容器;
});
}
由于initializeDBConnection希望返回容器对象,因此我如何获得initializeDBConnection解析容器对象的实例?@user1790300-请参阅对我答案的修改。假设container.bind().toConstantValue()
不是异步的,您可以在中返回容器。然后()
handler使其成为已解析的值。这很有效。非常感谢。问题,为什么容器的返回在该场景中有效,而不需要进行解析?@user1790300-来自的返回值。然后()
handler成为父承诺的已解析值。这就是的方式。然后()
有效。当您必须执行新承诺()
时,您只能手动执行解析()
。然后您只需使用处理程序。然后()
处理程序处理已解析的父承诺,您可以从处理程序控制已解析的值。然后()
处理程序使用返回值。