嵌套ClientContext executeQueryAsync()

时间:2016-10-20 12:17:28

标签: sharepoint ecmascript-5 sharepoint-jsom

我需要更改SharePoint列表工作流状态列的值。

让我们假设我们可以在一个列表中包含2到多个工作流列(当列表包含1个工作流状态列时,以下代码可用。)

问题是当它有多个工作流状态列时,它只更新最后一列,因为存在嵌套的executeQueryAsync调用。

我也尝试过Deferred / Promise - 请参阅第二个代码块。

<script type="text/javascript">
ExecuteOrDelayUntilScriptLoaded(initialize, "sp.js");

//Get our objects
function initialize() {
    var t0 = performance.now();
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    var list = web.get_lists().getById(_spPageContextInfo.pageListId)
    var fieldCollection = list.get_fields();
    var spField;
    context.load(fieldCollection);
    context.executeQueryAsync(Function.createDelegate(this, onFieldCollectionSucceeded), Function.createDelegate(this, onListDataFailed));

    function onFieldCollectionSucceeded(sender, args) {
        var fieldEnumerator = fieldCollection.getEnumerator();
        while (fieldEnumerator.moveNext()) {
            var field = fieldEnumerator.get_current();
            var fType = field.get_fieldTypeKind();
            //Value 28 correspond to SPWorkflowStatus
            if (fType === 28) {
                console.log(fieldEnumerator.get_current().get_title() + ": " + fType);

                spField = field;
                context.load(spField, "SchemaXml");
                context.executeQueryAsync(Function.createDelegate(this, onFieldSucceeded), Function.createDelegate(this, onListDataFailed));
            }
        }
    }

    function onFieldSucceeded(sender, args) {
        console.log("Schema changes processing for column: " + spField.get_title());
        var schema = spField.get_schemaXml();
        var newSchema = schema.replace('Abgelehnt', 'Rejected');
        spField.set_schemaXml(newSchema);
        spField.update();
        context.executeQueryAsync(
           Function.createDelegate(this, schemaChanged),
           Function.createDelegate(this, onListDataFailed));
    };

    function schemaChanged(sender, args) {
        console.log('Field Schema Updated');
    }

    function onListDataFailed(sender, args) {
        console.log('List Data fetch failed. ' + args.get_message() + 'n' + args.get_stackTrace());
    };

    var t1 = performance.now();
    console.log("Total Execution Time " + (t1 - t0) + " milliseconds.")
};

<script type="text/javascript">
//http://johnliu.net/blog/2015/12/convert-sharepoint-jsoms-executequeryasync-to-promise-in-the-prototype
ExecuteOrDelayUntilScriptLoaded(registerJsomPromise, "sp.js");
ExecuteOrDelayUntilScriptLoaded(initialize, "sp.js");

function initialize() {
    var t0 = performance.now();
    var context = new SP.ClientContext.get_current();
    var web = context.get_web();
    var list = web.get_lists().getById(_spPageContextInfo.pageListId)
    var fieldCollection = list.get_fields();
    var spField;
    context.load(fieldCollection);
    context.executeQueryAsync(Function.createDelegate(this, onFieldCollectionSucceeded), Function.createDelegate(this, onListDataFailed));
};

function onFieldCollectionSucceeded(sender, args) {
    var fieldEnumerator = fieldCollection.getEnumerator();
    while (fieldEnumerator.moveNext()) {
        var field = fieldEnumerator.get_current();
        var fType = field.get_fieldTypeKind();
        //Value 28 correspond to SPWorkflowStatus
        if (fType === 28) {
            console.log(fieldEnumerator.get_current().get_title() + ": " + fType);

            spField = field;
            context.load(spField, "SchemaXml");

            var promise = context.executeQuery();
            setTimeout(function () { }, 500);

            promise.done(function () {
                console.log("Schema changes processing for column: " + spField.get_title());
                var schema = spField.get_schemaXml();
                var newSchema = setSchema(schema);
                spField.set_schemaXml(newSchema);
                spField.update();
                context.load(spField);

                context.executeQueryAsync(
                   Function.createDelegate(this, schemaChanged),
                   Function.createDelegate(this, onListDataFailed));
            });
            promise.then(function (sArgs) {
                console.log('Field Schema Updated');
                //sArgs[0] == success callback sender
                //sArgs[1] == success callback args
            }, function (fArgs) {
                //fArgs[0] == fail callback sender
                //fArgs[1] == fail callback args.
                //in JSOM the callback args aren't used much - 
                //the only useful one is probably the get_message() 
                //on the fail callback
                var failmessage = fArgs[1].get_message();
            });
            //context.executeQueryAsync(Function.createDelegate(this, onListDataSucceeded), Function.createDelegate(this, onListDataFailed));
        }
    }
}

function schemaChanged(sender, args) {
    console.log('Field Schema Updated');
}

function onListDataFailed(sender, args) {
    console.log('List Data fetch failed. ' + args.get_message() + 'n' + args.get_stackTrace());
};

var t1 = performance.now();
console.log("Total Execution Time " + (t1 - t0) + " milliseconds.")


function registerJsomPromise() {

    SP.ClientContext.prototype.executeQuery = function () {
        var deferred = $.Deferred();
        this.executeQueryAsync(
            function () { deferred.resolve(arguments); },
            function () { deferred.reject(arguments); }
        );
        return deferred.promise();
    };


}

1 个答案:

答案 0 :(得分:0)

执行查询异步会更改迭代器的状态。这就是为什么你有一个奇怪的行为。你应该加载你的字段,更新它们,并在最后一次执行一次单独的执行来实际更新内容。该方法的唯一问题是,如果您的代码在某些时候失败,则所有更新都将处于待处理状态。因此需要仔细处理错误。