Javascript承诺:无法从函数中获取返回值

时间:2020-01-27 15:11:58

标签: javascript function ecmascript-6 promise es6-promise

我无法从函数中获取返回对象,因此可以在下一个应由promise.then()调用的函数中重用它。 努力研究,找不到解决方法。

engine.log基本上等同于我的应用程序中的console.log

firstRequest
    .then( function (result) {
            return secondRequest(result)
        },
        error => engine.log(error)
    )
    .then(
        result => engine.log(result), // result is undefined, need the object here
    )

let firstRequest = new Promise(function(resolve, reject) {
        http.simpleRequest({
            'method': 'GET',
            'url': theUrl,
            'dataType': 'json',
            'timeout': 6000,
        }, function (error, response) {
            if (error) {
                engine.log("Error: " + error)
                reject()
            }

            if (response.statusCode != 200) {
                engine.log("HTTP Error: " + response.status)
                reject()
            }

            myObject = JSON.parse(response.data)
            resolve(myObject)
        })
});

function secondRequest(request) {
    http.simpleRequest({
        'method': 'GET',
        'url': theSecondUrl,
        'dataType': 'json',
        'timeout': 6000,
    }, function (error, response) {
        if (error) {
            engine.log("Error: " + error);
        }

        if (response.statusCode != 200) {
            engine.log("HTTP Error: " + response.status);
        }

        myObject = JSON.parse(response.data)
        return myObject // this is not being returned, to the .then()
    })
}

2 个答案:

答案 0 :(得分:1)

JavaScript许诺是异步的。这意味着它们在事件循环中得到了解决,如果在调用.then()回调后立即兑现了诺言,那么您将按预期在下一个函数中获得该值。

JavaScript承诺是异步的,因为典型的API调用或数据库检索可能涉及网络延迟或返回数据的任何其他延迟。因此,用户会将这些延迟视为性能问题。为了避免这种影响,Javascript 事件循环异步运行承诺时就发挥了作用。这意味着在promise之后的代码很可能在解析或拒绝之前运行。因此,您的下一个函数在其代码运行时将没有“第一承诺”值。 在事件循环的下一个迭代或1个以上的迭代中,您的承诺可能会被解决/被拒绝,然后可能会填充相应的值。

解决方案=>

您应该使用async await来使任何异步代码在javascript中同步。

您可以在此处了解更多信息。 https://javascript.info/async-await

答案 1 :(得分:1)

首先,我看到了冗余代码,因此我将把您的请求合并为一个更通用的函数。似乎您不希望这样做的原因是您觉得必须将“请求”参数传递给第二个函数,但是请注意,您从未使用过它。在两种情况下都只传递一个URL即可。

在您的通用函数(在下面我称为“ makeRequest”)中,请确保返回诺言,否则您将无法定义。另外,请确保在解析对象上调用resolve,而不是return;

此外,我将使用catch来处理您的错误,这样无论何时发生错误,无论是第一个then还是第二个错误,您都可以捕获它。

顺便说一下,这是未经测试的,但是我认为其中的基本要点。

makeRequest('somewhere')
.then(result => makeRequest('theSecondUrl'))
.then(result => engine.log(result))
.catch(error => engine.log(error));

function makeRequest (url, method, datatype, timeout) {

    return new Promise(function(resolve, reject) {

        http.simpleRequest({
            'method': method || 'GET',
            'url': url,
            'dataType': datatype || 'json',
            'timeout': timeout || 6000,
        }, function (error, response) {

            if (error) {
                engine.log("Error: " + error)
                reject()
            }

            if (response.statusCode != 200) {
                engine.log("HTTP Error: " + response.status)
                reject()
            }

            // use 'let' or else you've made a globally scoped variable
            let parsed = JSON.parse(response.data) 
            resolve(parsed);

        });

    })

}