简体   繁体   English

链接承诺-正确的方法

[英]Chaining promises - correct methodology

I'm trying to create an excel add-in using Javascript that requires asynchronous functions return a JS promise to Excel and that the promise is resolved with the final value using the callback function. 我正在尝试使用需要异步函数的Javascript创建一个Excel加载项,并向Excel返回JS承诺,并使用回调函数将承诺与最终值一起解析。 I am new to promises and have spent hours reading and testing this out with no success, and was hoping someone could help me understand what I'm doing wrong. 我对承诺不陌生,花了数小时阅读并测试了此方法,但没有成功,并且希望有人可以帮助我了解我在做错什么。 Below is the code: 下面是代码:

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();
        });
    }

The second function getData is working as intended and returning a JS Object. 第二个函数getData按预期工作,并返回JS对象。 What I'm trying to accomplish with the TEST function is: 我想用TEST函数完成的是:

  1. Create a new promise - this needs to be resolved/returned as "Success" 创建一个新的诺言-这需要解决/返回为“成功”
  2. Call the API data with getData(temporarily running through a proxy to bypass CORS erros) 使用getData调用API数据(暂时通过代理运行以绕过CORS错误)
  3. Extract the meta.status value ("Success") 提取meta.status值(“成功”)

I've tried a number of different things but the current code write "last" and resolves an undefined data before the getData function completes. 我尝试了许多不同的操作,但是当前代码写“ last”并在getData函数完成之前解析未定义的数据。 Changing the "return (result.meta.status)" to "resolve (result.meta.status)" also doesn't help. 将“ return(result.meta.status)”更改为“ resolve(result.meta.status)”也无济于事。

Any assistance with what I'm doing wrong would be greatly appreciated. 对于我做错的任何帮助将不胜感激。

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
        })

that's how you chain promises. 这就是您兑现承诺的方式。 you don't resolve a promise within another promise, 您不会在另一个承诺中解决一个承诺,

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

You can use async/await since ES6 that solves a lot of this headache by simplifying the chain process into using await statements when letting promises resolve. ES6以来,您可以使用async/await因为它简化了链处理,使承诺得以解决时使用await语句,从而解决了许多麻烦。 I've updated your code block to use it, take a look: 我已经更新了您的代码块以使用它,看看:

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();
    });
}

Changes made : 所做的更改

  • TEST is now an async function . TEST现在是一个async function
  • Rather chaining the resolved promise from getData and resolving in TEST , you simply await the response from getData and then resolve it. 与其链接来自getData的已解析承诺并在TEST解析,您只需await来自getData的响应,然后对其进行解析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM