Javascript 没有承诺的价值观
我有一个针对sharepoint列表的查询,该列表返回一些数据,但对于每个项目,我必须进行另一个查询以获取其文档类型(内容类型),问题是这部分代码是在页面呈现后执行的Javascript 没有承诺的价值观,javascript,promise,Javascript,Promise,我有一个针对sharepoint列表的查询,该列表返回一些数据,但对于每个项目,我必须进行另一个查询以获取其文档类型(内容类型),问题是这部分代码是在页面呈现后执行的 var cname = getContentTypeOfCurrentItem(listItemValues['ID'].toString()); listItemsWithValues['Document Type'] = cname; function GetRelatedBillingDocumentsFromList(
var cname = getContentTypeOfCurrentItem(listItemValues['ID'].toString());
listItemsWithValues['Document Type'] = cname;
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 Scope="RecursiveAll">' + 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>' +
'</Query>' +
'</View>';
var billCyclesListId = '{c23bbae4-34f7-494c-8f67-acece3ba60da}';
spService.GetListItems(billCyclesListId, camlQuery, selectProperties)
.then(function (listItems) {
var listItemsWithValues = [];
if (listItems) {
var enumerator = listItems.getEnumerator();
var promises = [];
while (enumerator.moveNext()) {
var listItem = enumerator.get_current();
var listItemValues = [];
selectProperties
.forEach(function (propertyName) {
var value = listItem.get_item(propertyName);
if (propertyName === 'PwC_JobCodesMulti') {
jobvalue = '';
value.forEach(function (jobvalues) {
jobvalue += jobvalues.get_lookupValue() + ';';
});
listItemValues[propertyName] = jobvalue;
} else {
listItemValues[propertyName] = value;
}
//listItemValues[propertyName] = value;
});
listItemsWithValues.push(listItemValues);
}
var cname = getContentTypeOfCurrentItem(listItemValues['ID'].toString());
listItemsWithValues['Document Type'] = cname;
}
listItemsWithValues.forEach(function (listItem) {
var fileDirRef = listItem['FileRef'];
var id = listItem['ID'];
var title = listItem['Title'];
var serverUrl = _spPageContextInfo.webAbsoluteUrl.replace(_spPageContextInfo.webServerRelativeUrl, '');
var dispFormUrl = serverUrl + '/sites/billing/_layouts/15/DocSetHome.aspx?id=' + fileDirRef;
//listItem["FileRef"] = dispFormUrl;
//listItem["Bill Cycle"] = dispFormUrl;
var parentLink = listItem['FileRef'];
arrayofstrings = parentLink.split('/');
var billCycleFolderName = arrayofstrings[arrayofstrings.length - 2];
arrayofstrings.pop();
var hyperLink = '<a href="' + arrayofstrings.join('/') + '">' + billCycleFolderName + '</a>';
listItem['Bill Cycle'] = hyperLink;
});
var enhancedListItemValues = spService.SpSearchQuery.EnhanceSearchResults(listItemsWithValues, enhanceFunctions);
deferred.resolve(listItemsWithValues);
})
.catch(function (message) {
deferred.reject();
});
return deferred.promise;
}
function getContentTypeOfCurrentItem(id) {
var clientContext = new SP.ClientContext.get_current();
var oList = clientContext.get_web().get_lists().getByTitle('Bill Cycles');
listItem = oList.getItemById(id);
clientContext.load(listItem);
listContentTypes = oList.get_contentTypes();
clientContext.load(listContentTypes);
clientContext.executeQueryAsync(
Function.createDelegate(this, getContentTypeOfCurrentItemSucceeded),
function (error, errorInfo) {
$log.warn('Retrieving list item result failed');
deferred.reject(errorInfo);
}
);
}
function getContentTypeOfCurrentItemSucceeded(sender, args) {
var ctid = listItem.get_item('ContentTypeId').toString();
var ct_enumerator = listContentTypes.getEnumerator();
while (ct_enumerator.moveNext()) {
var ct = ct_enumerator.get_current();
if (ct.get_id().toString() == ctid) {
var contentTypeName = ct.get_name();
return contentTypeName;
}
}
}
var cname=getContentTypeOfCurrentItem(listItemValues['ID'].toString());
listItemsWithValues['Document Type']=cname;
函数GetRelatedBillingDocumentsFromList(选择属性、currentBillCyclePath、clientCode、jobCodes、enhanceFunctions){
$log.info('检索名称为['+currentBillCyclePath+']'的账单周期的相关账单文档);
var deferred=$q.deferred();
var webUrl=_spPageContextInfo.webAbsoluteUrl;
var viewFields=spService.ConvertSelectPropertiesToViewFields(selectProperties);
//查询必须返回同一客户机但在其他票据周期(而不是当前票据周期)中的单据
var camlQuery=''+视图字段+
'' +
'' +
'';
listItem['Bill Cycle']=超链接;
});
var enhancedListItemValues=spService.SpSearchQuery.EnhanceSearchResults(listItemsWithValues,enhanceFunctions);
延迟。解析(listItemsWithValues);
})
.catch(函数(消息){
拒绝();
});
回报。承诺;
}
函数getContentTypeOfCurrentItem(id){
var clientContext=new SP.clientContext.get_current();
var oList=clientContext.get_web().get_lists().getByTitle('Bill Cycles');
listItem=oList.getItemById(id);
clientContext.load(listItem);
listContentTypes=oList.get_contentTypes();
加载(listContentTypes);
clientContext.executeQueryAsync(
createDelegate(此,GetContentTypeOfCurrentItemSuccessed),
函数(错误,错误信息){
$log.warn('检索列表项结果失败');
延迟。拒绝(错误信息);
}
);
}
函数GetContentTypeOfCurrentItemSuccessed(发件人,参数){
var ctid=listItem.get_item('ContentTypeId').toString();
var ct_enumerator=listContentTypes.getEnumerator();
while(ct_枚举器.moveNext()){
var ct=ct_枚举器。获取当前值();
if(ct.get_id().toString()==ctid){
var contentTypeName=ct.get_name();
返回contentTypeName;
}
}
}
如何确保内容类型调用正确进行?我已经重构了您的示例,以了解代码的意图。我认为您需要更好地理解承诺的异步性质和作用域/闭包的概念(我认为您的代码根本不起作用,在许多方面,我在
oldscript.js
文件中包含了一篇评论)
我的示例使用一个存根对象来模拟提供者,但为了简短起见,我要说:关键是Promise.all
,这是一个工厂,它生成一个新的承诺,当所有承诺都得到解决时,该承诺就会得到履行
您需要为每个项目存储一个承诺,为每个ID保留未来的值(您的原始代码段只存储最后一个ID,这似乎是一个bug),当所有这些问题都解决后,您可以继续使用数据(稍后,也称为异步或延迟)
希望能有帮助
相关片段
function addContentType(listItem){
var promise = getContentTypeOfCurrentItem(listItem.ID.toString());
promise.then(function(cname){
listItem['Document Type'] = cname;
});
return promise;
}
function processListItems(listItems) {
var listItemsWithValues = listItems.map(listItemToValue);
var promises = listItemsWithValues.map(addContentType);
Promise.all(promises).then(youCanUseTheData);
function youCanUseTheData(){
/*
At this point, each listItem holds the 'Document Type' info
*/
listItemsWithValues.forEach(function (listItem) {
console.log(listItem);
});
}
我已经重构了您的示例,以了解代码的意图。我认为您需要更好地理解承诺的异步性质和作用域/闭包的概念(我认为您的代码根本不起作用,在许多方面,我在
oldscript.js
文件中包含了一篇评论)
我的示例使用一个存根对象来模拟提供者,但为了简短起见,我要说:关键是Promise.all
,这是一个工厂,它生成一个新的承诺,当所有承诺都得到解决时,该承诺就会得到履行
您需要为每个项目存储一个承诺,为每个ID保留未来的值(您的原始代码段只存储最后一个ID,这似乎是一个bug),当所有这些问题都解决后,您可以继续使用数据(稍后,也称为异步或延迟)
希望能有帮助
相关片段
function addContentType(listItem){
var promise = getContentTypeOfCurrentItem(listItem.ID.toString());
promise.then(function(cname){
listItem['Document Type'] = cname;
});
return promise;
}
function processListItems(listItems) {
var listItemsWithValues = listItems.map(listItemToValue);
var promises = listItemsWithValues.map(addContentType);
Promise.all(promises).then(youCanUseTheData);
function youCanUseTheData(){
/*
At this point, each listItem holds the 'Document Type' info
*/
listItemsWithValues.forEach(function (listItem) {
console.log(listItem);
});
}
.避开那条路!因此,在
getContentTypeOfCurrentItem
中有一个异步查询。我想您想在EnhanceSearchResults
中执行多个异步查询并返回结果?问题不清楚。你想同时履行承诺吗?你能更清楚地解释一下你的意图吗?避免这种情况!因此,在getContentTypeOfCurrentItem
中有一个异步查询。我想您想在EnhanceSearchResults
中执行多个异步查询并返回结果?问题不清楚。你想同时履行承诺吗?你能更清楚地解释你的意图吗?请在你的答案中发布相关代码,而不仅仅是一个链接。我需要重构/模拟许多代码以更好地理解(并测试这些代码是否有效),原始代码包含各种错误,我添加了一个代码片段,但您需要在plunk上挖掘才能在上下文中理解它。请在您的答案中发布相关代码,而不仅仅是链接。我需要重构/模拟许多代码以更好地理解(并测试这些代码是否有效),原始代码包含各种错误,我已经添加了一个片段,但您需要深入研究plunk,以便在上下文中理解它