带有承诺和单元/集成测试的异步Javascript

带有承诺和单元/集成测试的异步Javascript,javascript,unit-testing,asynchronous,Javascript,Unit Testing,Asynchronous,我对Javascript和异步的世界很陌生,这两种技术似乎都让我头疼 因此,我有一个第三方客户端API,它具有以下async方法getItem(id) 现在,我尝试根据父项的子项确定其状态: getStatus = function(ids) { var failedCount = 0; var successCount = 0; var warningCount = 0; ids.forEach(function(id) { //calling

我对Javascript和异步的世界很陌生,这两种技术似乎都让我头疼

因此,我有一个第三方客户端API,它具有以下
async
方法
getItem(id)

现在,我尝试根据父项的子项确定其状态:

getStatus = function(ids) {
    var failedCount = 0;
    var successCount = 0;
    var warningCount = 0;

    ids.forEach(function(id) {
        //calling the async function
        getItem(id).then(function(item) {
            var state = item.State;
            if(state == "Success") {
                successCount++;
            } else if(state == "Failed") {
                failedCount++;
            } else if(state == "Warning") {
                warningCount++;
            }
        });
    });
    if(failedCounter > 0) {
        return "Failed";
    } else if(warningCounter > 0) {
        return "Warning";
    } else if(successCounter == ids.length) {
        return "Success";
    } else {
        return "Not run yet";
    }
}
然后,为了确保我不会在途中破坏任何东西,我决定进行一些集成测试,因此我决定:

尝试调整
setTimeout
timeout,尝试使用
assert.async(2)
assert.async()
,每个文档中每个QUnit的默认值,但无济于事,最终结果每次都是一样的,即使经过一系列阅读并试图理解我也不知道我做错了什么:

1. failed     @ 2004 ms
Expected: "Failed"
Result:   undefined
Diff:   "Failed" undefined 

您的
getStatus
函数在任何异步调用解析之前返回一个结果。您需要使
getStatus
返回一个承诺,当所有其他承诺都通过以下方式解决时,该承诺将得到解决:

然后,您需要调整测试代码,使其使用promise而不是
setTimeout
。请注意,您可以从回调返回一个thenable对象,它将自动处理
承诺的解析

QUnit.cases([
    { title: "Success, Failed => Failed", ids: [1, 2], expectedStatus: "Failed" }
]).test("getStatus() test", function(params, assert) {
    return getStatus(params.ids).then(function(value) {
        assert.equal(value, params.expectedStatus);
    });
});

getItem(id)
调用是否需要以串联或串联方式完成parallel@JaromandaX没有一个承诺使用其他承诺的结果,因此,我想并行地说。从发布的代码来看,这似乎是一个合理的假设——但我们不知道未命名的第三方API的内在含义:PZ只是一个友好的提示,在代码块格式中使用
async
,可能会让一些Javascript开发人员感到困惑。承诺是在JS中实现异步的一种方式,但async/await则是另一回事。看见
var getStatus = function(ids) {
    var failedCount = 0;
    var successCount = 0;
    var warningCount = 0;

    return Promise.all(ids.map(function(id) {
        return getItem(id).then(function(item) {
            var state = item.State;
            if (state === "Success") {
                successCount++;
            } else if (state === "Failed") {
                failedCount++;
            } else if (state === "Warning") {
                warningCount++;
            }
        });
    })).then(function() {
        if (failedCounter > 0) {
            return "Failed";
        } else if (warningCounter > 0) {
            return "Warning";
        } else if (successCounter === ids.length) {
            return "Success";
        } else {
            return "Not run yet";
        }
    });
};
QUnit.cases([
    { title: "Success, Failed => Failed", ids: [1, 2], expectedStatus: "Failed" }
]).test("getStatus() test", function(params, assert) {
    return getStatus(params.ids).then(function(value) {
        assert.equal(value, params.expectedStatus);
    });
});