【问题标题】:How to get the value returned from a promise and use it in other file?如何获取从承诺返回的值并在其他文件中使用它?
【发布时间】:2019-08-27 17:42:56
【问题描述】:

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

此项目中有 5 个文件。 一个包含所有依赖注入的容器文件;包含我需要运行的功能的服务文件;一个控制器文件,它调用服务文件中的函数;一个app文件,它是最高级别的应用程序,它将调用所有的控制器文件,在这个例子中只有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 属性变为“Hello from service!”并能够 console.log 将其注销。调用顺序应该是:

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

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

我很确定我在 controller.js 中将其从 promise return 它搞砸了,因为如果我使用其他同步功能,它就可以工作。

请告诉我为什么我错了,如何让它发挥作用。

【问题讨论】:

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


    【解决方案1】:

    您不会返回您在 controller.doWork() 中创建的承诺。当您等待 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() 值的代码变得更长和/或更复杂时。

    【讨论】:

    • 成功了,谢谢朋友。我需要更多地了解承诺。所以要让它工作,我们基本上需要返回一个返回消息变量的承诺?
    • 是的,你的函数需要返回一个承诺。在您的情况下,如果您不想将响应存储在 this.message 中,您可以简单地编写“return this.service.doService();” doService 是一个承诺,所以你已经满足了这个要求。我将在帖子中添加一些内容以澄清 await 声明。
    • 谢谢,你是最棒的! :)
    猜你喜欢
    • 1970-01-01
    • 2019-11-02
    • 1970-01-01
    • 2017-02-07
    • 2020-03-23
    • 2022-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多