ReSharper关于ClosureOnModifiedVariable的警告-为什么?

时间:2020-04-29 16:42:46

标签: javascript scope warnings resharper

所以我在审查中遇到了这段代码:

int curActionCount = work.Actions.Count();
int noProgressCount = 0;

await Polly.Policy
    .Handle<IndexBatchException>() // One or more of the actions has failed.
    .WaitAndRetryForeverAsync(
        // Exponential backoff (2s, 4s, 8s, 16s, ...) and constant delay after 1 minute.
        retryAttempt => TimeSpan.FromSeconds( Math.Min( Math.Pow( 2, retryAttempt ), 60 ) ),
        (ex, _) =>
        {
            var batchEx = ex as IndexBatchException;
            work = batchEx.FindFailedActionsToRetry( work, d => d.Id );

            // Verify whether any progress was made.
            int remainingActionCount = work.Actions.Count();
            if ( remainingActionCount == curActionCount ) ++noProgressCount;
            curActionCount = remainingActionCount;
        } )
    .ExecuteAsync( async () =>
    {
        // Limit retries if no progress is made after multiple requests.
        if ( noProgressCount > 5 )
        {
            throw new TimeoutException( "Updating Azure search index timed out." );
        }

        // Only retry if the error is transient (determined by FindFailedActionsToRetry).
        // IndexBatchException is also thrown for unknown document IDs;
        // consider them outdated requests and ignore.
        if ( curActionCount > 0 )
        {
            await _search.Documents.IndexAsync( work );
        }
    } );

,该“ // ReSharper disable”注释使我暂停了。 我试图调查一下,发现了-https://www.jetbrains.com/help/resharper/AccessToForEachVariableInClosure.html

但是,我尝试删除注释,然后按照该链接的说明进行操作,在作用域内创建一个变量来存储值,但警告并没有消失。

此外,尽管有警告,但它的行为似乎与设计相符-i的值正确更改,最后'data'变量存储正确/期望的值。

所以,我的问题是...为什么ReSharper为此警告?代码中是否存在实际问题,还是ReSharper中存在错误?如果是前者,我应该如何修复代码?如果是后者,此警告永远是否正确(因此我们应该保留禁用注释),或者我应该将检查严重性更改为从不显示此警告?

更新

对代码的以下更改使警告消失了:

        var permissions = $("#" + me.map.permissionsGridHtmlId).data("kendoGrid").dataSource.data();
        var data = form.serializeArray();
        for (var i = 0; i < permissions.length; i++) {
            var record = permissions[i].toJSON();
            $.each(record, function (key, value) {
                data.push({
                    // ReSharper disable once ClosureOnModifiedVariable
                    name: "Permissions[" + i + "]." + key,
                    value: value
                });
            });
        }

我仍然想知道为什么为什么存在,但是,当两个代码片段的行为相同时。

1 个答案:

答案 0 :(得分:1)

只有在变量修改后将执行lambda(您的情况下为函数参数)时,才可以访问修改后的闭包。在您的情况下,$.each应该立即执行lambda,所以这不是问题。但是ReSharper不知道被调用函数是立即执行传递的lambda还是将其存储以供以后执行,尤其是在具有动态类型的JavaScript中。因此,它始终会发出警告。

请注意,您找到的文章涉及C#,并且其建议的修复仅对C#有效。您无法使用var i1 = i来解决JS中的问题,因为i1声明的变量var具有函数作用域,并且您需要使其具有块作用域。因此,如果可以使用ECMAScript 2015,则可以使用letconst声明具有块范围的变量,例如:

var permissions = $("#" + me.map.permissionsGridHtmlId).data("kendoGrid").dataSource.data();
var data = form.serializeArray();
for (var i = 0; i < permissions.length; i++) {
    var record = permissions[i].toJSON();
    let i1 = i;
    $.each(record, function (key, value) {
        data.push({
            name: "Permissions[" + i1 + "]." + key,
            value: value
        });
    });
}
相关问题