Promise Never Resolve 使用 Axios

如何解决Promise Never Resolve 使用 Axios

我正在使用 Wdio 并定义一个客户报告器以与 testrails api 集成。计划是使用 axios 在测试钩子内发出这些请求。

不幸的是,我无法让 axios 返回任何关于请求的有效数据。在大多数情况下,当我们 await 响应时,线程会完全停止执行而没有任何日志输出。如果我把它弄得足够好,有时我可以让它返回一个解决的承诺,但我无能为力最终解决这个承诺。

此外,在我的所有尝试中,testrails 都没有收到请求(我也测试了其他一些网址,我很确定问题不在目的地)。

我已确保网络访问和安全性不是因素。我们还尝试使用 axios 帖子和直接的 axios() 方法,但没有成功。

我将复制下面的文件,我已经添加了大约十几个尝试/配置,并在每个尝试/配置上附上了关于我们得到什么的注释。问题的关键在于 addRun() 方法

在大多数情况下,我们似乎从未解决过承诺。有一个例外,我们根本不与响应交互,只需登录 then() 语句即可。如果我们这样做,我们可以看到那些日志,但是 axios 调用的结果永远不会生效(运行不是在 testrails 中创建的)。

const WdioReporter = require('@wdio/reporter').default
const axios = require('axios').default;

module.exports = class TestrailsReporter extends WdioReporter{
    constructor(options) {
        /*
         * make reporter to write to the output stream by default
         */
        options = Object.assign(options,{ stdout: true })
        super(options)
    }

    // I have tried marking this as both async and not,no difference
    async onRunnerEnd(suite) {
        console.log("CHECKPOINT RUNNER END")
        this.recordResults(caseIds[5],results[5],'renters api tests',5);
    }
    /**
     * takes the results from a test suite and records them in testrails
     * @param suiteId -- the suite defined in the testrails project
     * @param projectId -- the project id defined in the testrails project
     * @param caseIds -- a list of cases with which to create the test run
     * @param results -- a list of case:result pairings
    */
    async recordResults(caseIds,results,name,projectId) {
        console.log(`CHECKPOINT RECORDING RESULTS ${projectId}`)
        let testRun = await this.addRun(results['suiteId'],caseIds['cases'],projectId);
        testRun.then(console.log)
        await this.addResults(testRun,results['cases']);
    }

    async addRun(suiteId,caseIds,name = '',projectId) {
        console.log("CHECKPOINT ADD RUN")
        let addrunconfig = {
            method: 'post',url: `https://REDACTED.testrail.io/index.PHP?/api/v2/add_run/${projectId}`,headers: {
                'Content-Type': 'application/json',Authorization: token,Cookie: 'tr_session=041c4349-688f-440a-95a3-afc29d39320a'
            },data: JSON.stringify({
                suite_id: suiteId,include_all: false,case_ids: caseIds,name: name
            })
        };

        // let x = axios.get('https://www.google.com/')
        // console.log(x)

        axios.defaults.timeout = 1000;

        // THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT,RETURNS PENDING PROMISE TO RESPONSE
        // let response = axios(addrunconfig)
        //     .then(function (response) {
        //         console.log("WHAAAT?")
        //         return response.data.id;
        //     })
        //     .catch(function (error) {
        //         console.log("HELP!")
        //         console.log(error);
        //     });
        // THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT,NO LOGGING APPEARS AFTER
        let response = await axios(addrunconfig)
            .then(function (response) {
                console.log("WHAAAT?")
                return response.data.id;
            })
            .catch(function (error) {
                console.log("HELP!")
                console.log(error);
            });

        // THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT
        // await axios.post(`https://REDACTED.testrail.io/index.PHP?/api/v2/add_run/${projectId}`,addrunconfig)
        //     .then(
        //         function (response){
        //             console.log('WHAAAT?')
        //             console.log(response)
        //             console.log('NO WAY?')
        //         })

        // THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT,BUT RETURNS A PENDING PROMISE TO RESPONSE
        // let response = axios.post(`https://REDACTED.testrail.io/index.PHP?/api/v2/add_run/${projectId}`,addrunconfig)
        //     .then(
        //         function (run){
        //             console.log('WHAAAT?')
        //             console.log(run)
        //             console.log('NO WAY?')
        //         })

        // THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT,addrunconfig)
        //     .then(
        //         function (run){
        //             console.log('WHAAAT?')
        //         })

        // THIS DOES NOT EXECUTE THE CODE INSIDE THE THEN STATEMENT,addrunconfig)
        //     .then(run => {
        //             console.log('WHAAAT?')
        //         })

        // THIS EXECUTES THE CONSOLE.LOG INSIDE THE THEN STATEMENT,BUT NOT AFTER
        // let response = await axios.post(`https://REDACTED.testrail.io/index.PHP?/api/v2/add_run/${projectId}`,addrunconfig)
        //     .then(console.log('WHAAAT?'))

        // THIS EXECUTES THE CONSOLE.LOG INSIDE THE THEN STATEMENT,AND AFTER
        // let response = axios.post(`https://REDACTED.testrail.io/index.PHP?/api/v2/add_run/${projectId}`,addrunconfig)
        //     .then(console.log('WHAAAT?'))

        // EXECUTES THE CONSOLE.LOG INSIDE THE THEN STATEMENT,nothing FROM THE CATCH,AND nothing AFTER
        // const response = await axios(addrunconfig).then(console.log("HI")).catch(function (error) {
        //     console.log("HELP!")
        //     console.log(error);
        // });

        console.log("ANYTHING")
        console.log(response)
        return response
    }```

解决方法

想通了,这是 WDIOReporter 父类不能很好地处理来自 axios 的异步调用。解决方案在这里找到: https://github.com/webdriverio/webdriverio/issues/5701

,

您是否尝试过使用 await axios.post(...) 而不是在 addRunConfig 对象中定义所有内容?

不确定它是否有所作为,但值得一试。

,

这里对定义函数、调用函数和异步函数的概念有些混淆。

首先:如果您正在调用一个异步函数并且不希望您的调用函数在该异步函数返回之前返回,您希望await 该调用。

在这种情况下,您的 recordResults 函数等待某些东西,因此是异步的。因此,您可能希望 onRunnerEnd 等待您对 recordResults 的调用。如果您不这样做,该函数将过早终止并且可能不会等待结果。

async onRunnerEnd(suite) {
    console.log("CHECKPOINT RUNNER END")
    await this.recordResults(caseIds[5],results[5],'renters api tests',5);
}

其次,如果同时使用 thenawaitawait 表达式返回的值是 then 中函数返回的任何值。因此,您在 then 调用的函数内没有返回值的所有尝试都将永远不会返回空承诺之外的任何内容。没有理由将这些概念结合起来。

第三,将函数调用(而不是声明或引用)放入 then 子句中,将立即调用该函数。 IE。 .then(console.log('WHAAAT?')) 只是立即调用 console.log 并注册一个不存在的函数作为 then 的回调(因为 console.log 不返回函数引用)。

最后,传递未绑定的函数一般是行不通的。根据 testRun.then(console.log)then 的实现,执行 console.log 之类的操作将不起作用。为了安全起见,请执行 testRun.then(console.log.bind(console)testRun.then((x) => console.log(x))


因此,首先,在 onRunnerEnd 中添加 await,然后只使用 await 结果,而不要在 then 中使用任何 addRun 或 catch:

async addRun(suiteId,caseIds,name = '',projectId) {
    console.log("CHECKPOINT ADD RUN")
    let addRunConfig = {
        method: 'post',url: `https://REDACTED.testrail.io/index.php?/api/v2/add_run/${projectId}`,headers: {
            'Content-Type': 'application/json',Authorization: token,Cookie: 'tr_session=041c4349-688f-440a-95a3-afc29d39320a'
        },data: JSON.stringify({
            suite_id: suiteId,include_all: false,case_ids: caseIds,name: name
        })
    };

    // let x = axios.get('https://www.google.com/')
    // console.log(x)

    axios.defaults.timeout = 1000;

    let response = await axios(addRunConfig);
    console.log(response);
    console.log(response.data.id);
    return response.data.id;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?