如何将第二个promise的值添加到值数组中

时间:2017-12-04 09:50:51

标签: javascript promise

我不确定问题的标题是否有意义,但可能会使用代码来帮助我解释它。

我有以下代码,但默认情况下不会在列表项值中返回sharepoint内容类型。

function getListItems(listId, camlQueryString, selectProperties){  
    var deferred = $q.defer();
    var context = SP.ClientContext.get_current();
    var web = context.get_web();

    var list = web.get_lists().getById(listId);

    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml(camlQueryString);

    var listItems = list.getItems(camlQuery);

    //var includesString = "Include(ID,Title,AssignedTo, WorkflowOutcome, ApproverComments, FileRef, WorkflowItemId, Created, Modified)"; // + selectProperties.join(", ") +  ")";
    if(selectProperties) {
        var includesString = convertSelectPropertiesToIncludesString(selectProperties);
        context.load(listItems, includesString);
    } else {
        context.load(listItems);
    }
    context.executeQueryAsync(
        function() {
            $log.info("Successfully retrieved list item result");

            deferred.resolve(listItems);
        },
        function(error, errorInfo) {
            $log.warn("Retrieving list item result failed");

            deferred.reject(errorInfo);
        }
    );
    return deferred.promise;
}

我正在尝试转换此方法以获取相同数组值中的内容类型名称

function getListItemswithContentType(listId, camlQueryString, selectProperties){  
    var deferred = $q.defer();
    var context = SP.ClientContext.get_current();
    var web = context.get_web();

    var list = web.get_lists().getById(listId);

    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml(camlQueryString);

    var listItems = list.getItems(camlQuery);

    //var includesString = "Include(ID,Title,AssignedTo, WorkflowOutcome, ApproverComments, FileRef, WorkflowItemId, Created, Modified)"; // + selectProperties.join(", ") +  ")";
    if(selectProperties) {
        var includesString = convertSelectPropertiesToIncludesString(selectProperties);
        context.load(listItems, includesString);
    } else {
        context.load(listItems);
    }

    context.executeQueryAsync(Function.createDelegate(this, SuccessHandler),Function.createDelegate(this, ErrorHandler));

    return deferred.promise;
}

function SuccessHandler(result) {
    listItemEnumerator = listItems.getEnumerator();
    while (listItemEnumerator.moveNext()) {
        oListItem = listItemEnumerator.get_current();
        var CT = oListItem.get_contentType();
        context.load(CT);
        context.executeQueryAsync(
            (function (contentobject) {
                return function () {
                    var value = contentobject.get_name();
                    alert("VAL: "+value);
                };
            }(contentobject)),
            function () {
                alert("No Success");
            }
        );
    }               
}

function ErrorHandler(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

但是你可以看到这里有2个异步执行,在成功处理程序方法中我返回内容类型名称,但我不知道如何将该内容类型名称作为值添加到listitems数组。

更新1

来电方法

function GetRelatedBillingDocumentsFromList(selectProperties, currentBillCyclePath, clientCode, jobCodes, engagementCode, enhanceFunctions) {
                $log.info("Retrieving related billing documents for bill cycle with name [" + currentBillCyclePath + "]");                  
                var deferred = $q.defer();
                var webUrl = _spPageContextInfo.webAbsoluteUrl;
                var viewFields = spService.ConvertSelectPropertiesToViewFields(selectProperties);
                // query must return the documents for the same client but in other bill cycles not the current one
                var camlQuery = '<View>' +   viewFields + 
                        '<Query>' +
                            '<Where>' +
                                //'<And>' +
                                    '<Eq>' +
                                        '<FieldRef Name="ClientCode" />' +
                                        '<Value Type="Text">'+ clientCode + '</Value>' +
                                    '</Eq>' +
                                //  '<Neq>' +
                                //      '<FieldRef Name="ContentType" />' +
                                //      '<Value Type="Computed">Bill Cycle</Value>' +
                                //  '</Neq>' +
                                //'</And>' +
                            '</Where>' +
                            //'<QueryOptions>' +
                            //  '<ViewAttributes Scope="RecursiveAll" />' +
                            //'</QueryOptions>' +
                        '</Query>' +
                    '</View>';

                var billCyclesListId = "{c23bbae4-34f7-494c-8f67-acece3ba60da}";                    
                spService.GetListItemswithContentType(billCyclesListId, camlQuery, selectProperties)
                .then(function(listItems) {
                    var listItemsWithValues = [];
                    if(listItems) {
                        var enumerator = listItems.getEnumerator();
                        while (enumerator.moveNext()) {
                            var listItem = enumerator.get_current();
                            var listItemValues = [];                                
                            selectProperties
                            .forEach(function(propertyName) {                               
                                var value = listItem.get_item(propertyName);
                                listItemValues[propertyName] = value;
                            });

                            listItemsWithValues.push(listItemValues);
                        }
                    }

                    // Create the full item url
                    listItemsWithValues.forEach(function(listItem) {
                        var fileDirRef = listItem["FileRef"];
                        var id = listItem["ID"];
                        var serverUrl = _spPageContextInfo.webAbsoluteUrl.replace(_spPageContextInfo.webServerRelativeUrl,"");                          
                        var dispFormUrl = serverUrl + fileDirRef + "/DispForm.aspx?ID=" + id;
                        listItem["FileRef"] = dispFormUrl;
                    });

                    var enhancedListItemValues = spService.SpSearchQuery.EnhanceSearchResults(listItemsWithValues, enhanceFunctions);                       
                    deferred.resolve(listItemsWithValues);
                })
                .catch (function (message) {
                    deferred.reject();
                });

                return deferred.promise;
            }

1 个答案:

答案 0 :(得分:1)

如果您使用的是较旧的javascript引擎,可能以下内容仍然有用,您可能需要了解如何对{f} Promise.allnew Promise进行polyfil。如果箭头功能不起作用,您可以将e => z替换为function(e){return z;}

function SuccessHandler(result) {
  listItemEnumerator = listItems.getEnumerator();
  const promises = [];
  while (listItemEnumerator.moveNext()) {
    oListItem = listItemEnumerator.get_current();
    var CT = oListItem.get_contentType();
    context.load(CT);
    promises.push(
      new Promise(
        (resolve,reject) =>
          context.executeQueryAsync(
            //if contentobject is shared mutable object you're in trouble
            //  that doesn't work with concurrently running code that depends on it
            //  if it's mutable then prividing it in a closure with the IIFE isn't going
            //  to save you either
            (function (contentobject) {
              return function () {
                var value = contentobject.get_name();
                console.log("VAL: " , value);
                //not sure what it is you want to return here
                return [value,result];
              };
            }(contentobject)),
            function () {
              console.log("No Success");
            }
          )
      )
    );
    return Promise.all(promises)
    .then(
      results => {
        results.forEach(
          //just log all the results, you can remove the then
          //  if this was what you need
          ([value,result]) => console.log("value:",value,"result",result)
        );
        return result;
      }
    )
  }
}

如果调用getListItemswithContentType的函数需要知道它何时完成,您可以返回一个承诺。

return new Promise(
  (resolve,reject) =>
    context.executeQueryAsync(
      x=>SuccessHandler(x).then(resolve,reject)
      ,error=>reject(error)
    )
);