【问题标题】:Javascript how await promise inside extend ErrorJavascript如何在扩展错误中等待承诺
【发布时间】:2020-02-11 05:12:00
【问题描述】:

我目前正在尝试扩展 javascript 的标准错误类以解决进程问题,更准确地说,我想在抛出我的 customError 时检查 FTP 数据。问题是它在抛出之前从不等待等待函数完成。 awaited 函数也返回一个 Promise。

就我而言,我的班级有这个示例代码,请注意,remoteFs 只是一个自定义模块,其中包含我用于操作远程 FTP 数据的函数。

module.exports = class processError extends Error {

    constructor(args) {
        super(args);

        this.name = "customError"
        this._folder = "./test/"
        this._credentials = {
                host: 'my.host.com',
                user: 'username',
                password: 'passwd123',
            }

        return (this._errorProcess());
    }

    async _errorProcess () {

        try {
            // The function below is basic FTP list and should return a promised true/false if the folder exists or not.
            let IsThereFolder = await remoteFs.EntityExist(this._credentials, this._folder)
        } catch (err) {
            throw new Error("Fatal error in error handler:", err)
        }

        console.log("Should I create folder ?", IsThereFolder )
        return (this);
    }
}

我尝试了几种方法让构造函数等待,例如从 init() 函数调用 _errorProcess,该函数会在从构造函数调用后返回它。我还尝试将此函数放在类范围之外,但似乎没有任何工作正常,我总是在收到我的承诺之前得到抛出输出。

module.exports = {

EntityExist: function (credentials, toFind) {
       var c = new Client();
       let entityExist = false;

       return new Promise((resolve, reject) => {
           console.log("CREDENTIALS ->", credentials)
           c.on('ready', function () {
               console.log("Connection established");
               c.on('error', function (err) {
                   console.log(err);
                   reject(err);
               })
               c.list(toFind, (err, list) => {
                   if (err) throw err;

                   for (let i = 0; i < list.length; i++) {
                       if (list[i].name == toFind) { entityExist = true; }
                   }
                   c.on('end', () => { resolve(entityExist); })
                   c.end();
               });
           });
           console.log("Before connect")
           c.connect(credentials);
       })
   }
};

这是我执行此操作得到的实际输出:

CREDENTIALS -> { host: 'my.host.com',                                                       
  user: 'username',                                                                                    
  password: 'passwd123' }                                                                                  
Before connect                                                                                          

C:\path_to_project\includes\file.js:62 
                        throw new handleError("Testing custom error: " + err); break;    
                        ^                                                                               
[object Promise]

npm ERR! code ELIFECYCLE
npm ERR! errno 1
(...)

如您所见,它不会等待承诺返回,甚至不会到达 EntityExist 函数上的“已建立连接”日志(请不要认为此函数在其他情况下可以正常工作)。

实际上,我什至不知道是否可以直接从构造函数执行此类操作。 我希望上下文足够清楚,感谢您的时间!

【问题讨论】:

  • 你试过return await (this._errorProcess()); 吗?
  • 我刚试过,显然这是不可能的,并抛出错误提示:ReferenceError: await is not defined
  • 您不能在全局或构造函数范围内使用 async/await
  • 是的,这就是我从文档中得到的,是否有任何解决方法可以让我在抛出和退出此类范例的程序之前继续处理一些数据?

标签: javascript node.js constructor async-await extends


【解决方案1】:

await 运算符用于等待 Promise。它只能在异步函数中使用。

这意味着你不能在全局范围或类构造函数中使用。

使用 Promise 的构造函数是一种不好的做法,因为您将无法同时获得该类 (link to another stackoverflow answer)

从技术上讲,您可以从构造函数返回 Promise,但这不是他的目的。

在你的情况下,你可以在调用 throw 之前使用一个函数,这并不漂亮,但它可以完成工作。

作为:

async generateAsyncError(asyncFn) {
  await asyncFn();

  throw new Error();
}

在这里你可以在抛出错误之前使用异步。但请记住,在异步函数完成之前不会抛出错误。

【讨论】:

  • 是的,不是我期待的最好的,但它确实工作得很好,感谢您的帮助。
猜你喜欢
  • 2020-10-31
  • 2018-08-27
  • 1970-01-01
  • 2016-11-29
  • 2019-06-30
  • 2020-06-06
  • 2017-12-08
  • 2018-09-12
相关资源
最近更新 更多