如何获取承诺的返回值并将其用于其他文件?

时间:2019-08-27 17:42:56

标签: javascript node.js dependency-injection promise ioc-container

我创建了一个小项目来显示问题。

该项目中有5个文件。 一个包含所有依赖项注入的容器文件;包含我需要运行的功能的服务文件;在服务文件中调用功能的控制器文件;一个应用程序文件是最高级的应用程序,它将调用所有控制器文件,在此示例中只有1个;一个index.js文件,它是应用程序的起点。

container.js:

const {
    createContainer,
    asValue,
    asFunction,
    asClass,
} = require('awilix');

const container = createContainer();

const Controller = require('./controller');
const Service = require('./service');

container.register({
    controller: asClass(Controller).singleton(),
    service: asClass(Service).singleton(),
})

const App = require('./app');

container.register({
    app: asClass(App).singleton(),
})

module.exports = container;    

service.js:

module.exports = class Service {

    doService() {
        return new Promise(resolve => {
            setTimeout(() => resolve("Hello from service!"), 2000);
        });
    }

}

controller.js:

module.exports = class Controller {
    constructor({ service }) {
        this.service = service;
    }

    doWork() {
        this.service.doService().then(response => {
            this.message = response;
            return this.message;
        })
    }
}

app.js:

module.exports = class App {
    constructor({ controller }) {
        this.controller = controller;
    }

    async start() {
        try {
            this.doc = await this.controller.doWork();
        } catch (err) {

        }
        console.log(this.doc);
    }
}

index.js:

const container = require('./container');

const app = container.resolve('app');

app.start();

我的目标是我可以看到app.js中的doc属性变成“服务中的你好!”并能够进行console.log退出。呼叫顺序应为:

index.js-> app.js-> controller.js-> service.js-> controller.js-> app.js

使用awilix js将所有依赖项注入到container.js中。

我非常确定我在controller.js中从promise返回了它,因为如果我使用其他同步功能,它会起作用。

请让我知道我为什么做错了,如何使它起作用。

1 个答案:

答案 0 :(得分:2)

您不返回您在controller.doWork()中创建的promise。等待controller.doWork()的结果时,在“启动”函数中没有任何值。该函数不会将承诺或与此相关的任何内容返回给“等待”。

module.exports = class Controller {
constructor({ service }) {
    this.service = service;
}

//Needs to return a value.
doWork() {
    // This is a promise, you need to return it.
    //this.service.doService().then(response => {
    //    this.message = response;
    //    return this.message;
    //})

    return this.service.doService().then(response => {
        this.message = response;
        return this.message;
    })
}

app.js中的await语句是类似以下内容的语法糖:

 this.controller.doWork().then(response => {
      this.doc = response;
 });

我们可以使用await来“自动”解开Promise返回的值,并将其分配给变量。

它还暂停了函数“ start”,这使我们避免了必须在“ then”语句中编写函数的其余部分:

this.doc = await this.controller.doWork();
if (this.doc.type === "error") { 
    throw new Error(this.doc) 
}

比以下清洁得多

this.controller.doWork().then(response => {
    this.doc = response;
    if (this.doc.type === "error") { 
        throw new Error(this.doc) 
    }
});

尤其是依赖于doWork()值的代码变得更长和/或更复杂。