javascript - 如何获取从 promise 返回的值并在其他文件中使用它?

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

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

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

容器.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 注入(inject)到 container.js 中。

我非常确定我搞砸了从controller.js中的promise返回它,因为如果我使用其他同步功能它就可以工作。

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

最佳答案

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

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() 值的代码变得更长和/或更复杂时。

关于javascript - 如何获取从 promise 返回的值并在其他文件中使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57679790/

相关文章:

javascript - GWT javascript 未捕获异常

javascript - Node.js 异步文件写入 (svg2img)

node.js - 如何使用 ExpressJS 在同一个响应对象上多次渲染?

javascript - webpack.js 中的 yargs.parse 错误

asp.net-mvc - 针对各种应用程序的 Autofac 模块扫描

javascript - 如何创建自动重定向到特定链接的 chrome 扩展程序?

javascript - onsubmit内部没有调用JS表单验证函数

javascript - 将一个字符串一分为二,保持单词完整并返回它们

java - 如何使用 Spring Boot 注入(inject)以 InputStreamReader 作为参数的 BufferedReader?

java - 如何将资源映射到枚举常量?