链接承诺-正确的方法

时间:2018-08-02 11:21:15

标签: javascript promise

我正在尝试使用需要异步函数的Javascript创建excel加载项,并向Excel返回JS承诺,并使用回调函数将承诺解析为最终值。我对承诺不陌生,花了数小时阅读并测试了此方法,但没有成功,并且希望有人可以帮助我了解我在做错什么。下面是代码:

function TEST(num1) {
    return new Promise(function (resolve) {  
        var corsproxy = "https://cors-anywhere.herokuapp.com/"
        var apiurl = "https://randomapi.com/testapi"

        var data = getData(corsproxy+apiurl).then(function(result){
            console.log ("here it comes")    
            console.log(result.meta.status)  /// This returns "Success"
            return (result.meta.status)      /// I need this to be resolved
        })
        console.log("last")
        resolve(data)
    })
};

/// Get JSON
    function getData(url) {
        return new Promise(function (resolve, reject) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.responseType = 'json';
            xhr.onload = function () {
                try {
                    if (xhr.status === 200) {
                        resolve(xhr.response);
                    }
                    else if (xhr.status !== 200) {
                        reject({
                            error: 'Request failed. ' + xhr.response
                        });
                    }
                } catch (e) {
                    reject({
                        error: e
                    });
                }
            };
            xhr.send();
        });
    }

第二个函数getData正在按预期方式工作并返回JS对象。我要通过TEST函数完成的任务是:

  1. 创建新的承诺-需要解决/将其返回为“成功”
  2. 使用getData调用API数据(暂时通过代理运行以绕过CORS错误)
  3. 提取meta.status值(“成功”)

我尝试了许多不同的操作,但是当前代码写“ last”并在getData函数完成之前解析未定义的数据。将“ return(result.meta.status)”更改为“ resolve(result.meta.status)”也无济于事。

对于我做错的任何帮助,将不胜感激。

2 个答案:

答案 0 :(得分:1)

function TEST(num1) {
        var corsproxy = "https://cors-anywhere.herokuapp.com/"
        var apiurl = "https://randomapi.com/testapi"

        return getData(corsproxy+apiurl)
}

TEST(valofnum1).then(function(result){
            console.log ("here it comes")    
            console.log(result.meta.status)  /// This returns "Success"
            return (result.meta.status)      /// Needs to be resolved
        })

这就是您兑现承诺的方式。您不会在另一个承诺中解决一个承诺,

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

答案 1 :(得分:1)

您可以使用async/await,因为ES6通过简化链式过程,简化了履行承诺时使用await语句,从而解决了很多麻烦。我已经更新了您的代码块以使用它,看看:

async function TEST(num1) {
    return new Promise(function (resolve) {  
        var corsproxy = "https://cors-anywhere.herokuapp.com/"
        var apiurl = "https://randomapi.com/testapi"

        var result = await getData(corsproxy+apiurl);

        resolve(result.meta.status)
    })
};

/// Get JSON
function getData(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.responseType = 'json';
        xhr.onload = function () {
            try {
                if (xhr.status === 200) {
                    resolve(xhr.response);
                }
                else if (xhr.status !== 200) {
                    reject({
                        error: 'Request failed. ' + xhr.response
                    });
                }
            } catch (e) {
                reject({
                    error: e
                });
            }
        };
        xhr.send();
    });
}

所做的更改

  • TEST现在是async function
  • 您可以将getData的响应简单地TEST并加以解决,而不是将await的已解决的承诺链接起来并在getData中进行解决。