node.js:Promse出现了一个奇怪的问题';那就不打电话了

node.js:Promse出现了一个奇怪的问题';那就不打电话了,node.js,typescript,es6-promise,Node.js,Typescript,Es6 Promise,我正在处理以下Promise场景,不理解为什么第二个then条件在设置方法中没有被击中。当这段代码在app.js中运行时,我看到initialize()在何处被命中,它等待数据库连接按预期进行,但一旦initialize中达到解析条件,就不会调用任何其他内容。我在catch中设置了断点,但从未调用过断点;在设置方法中也没有达到捕获。我希望在完成后立即调用initializeAppSettings 我不明白这里出了什么问题。我真的需要有人来回顾和解释我在这个承诺场景中犯了什么错误 setup =

我正在处理以下Promise场景,不理解为什么第二个then条件在设置方法中没有被击中。当这段代码在app.js中运行时,我看到initialize()在何处被命中,它等待数据库连接按预期进行,但一旦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;
}
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成为父承诺的已解析值。这就是
的方式。然后()
有效。当您必须执行
新承诺()
时,您只能手动执行
解析()
。然后您只需使用
处理程序。然后()
处理程序处理已解析的父承诺,您可以从
处理程序控制已解析的值。然后()
处理程序使用返回值。