Я пытаюсь использовать обещания с петлями и вложенными функциями, которые находятся в пределах некоторых из этих циклов. У меня есть ряд функций, которые должны возвращать элементы списка SharePoint из вызовов REST - как только они выполняются, затем вызывается другая функция, которая использует данные, которые были возвращены.Использование обещаний с петлями и вложенными функциями
Поскольку в каждом из них имеется несколько списков, а затем несколько элементов списка, я использовал цикл while для каждого вызова REST, а оттуда данные (элементы списка) помещаются в объекты. Эти объекты помещаются в массив, и это то, что использует вторая функция.
У меня возникли проблемы с получением ответов от обещаний. Я думал, что у вас есть несколько обещаний, которые попадают в массив, а затем, наконец, используйте Promise.all
, чтобы увидеть, все ли разрешено до использования then
. Проблема в том, что все обещания остаются pending
, так как я не возвращаю resolve
правильно. См. Ниже.
function onQuerySuccess(sender, args) {
var itemEnumerator = items.getEnumerator();
while (itemEnumerator.moveNext()) {
var promise = new Promise(function (resolve, reject) {
var item = itemEnumerator.get_current();
item = item.get_item('URL');
var itemUrl = item.get_description();
getRequestItemsFromList(itemUrl);
});
promises.push(promise); // all promises are present, but their status is pending
}
console.log(promises);
Promise.all(promises).then(function (val) {
console.log(val);
execFuncs(); // function to execute once all the above are done
}).catch(function (response) {
console.log(response);
});
}
Потому что есть много функций, участвующих, так это порядок исполнения:
getRequestItemsFromList //gets url for each list
execCrossDomainRequest (on success call) // makes REST call to get list and its items
cleanData // trims data and puts it in objects
Последнее, где я полагал, что я называю Promise.resolve()
так, что конец линии.
В любом случае, это не работает. Я проверил другие темы, но я пытаюсь сделать это без использования каких-либо библиотек. Заранее спасибо.
Edit:
Полный соответствующий код:
var promises = [];
window.requests = [];
function getRequestLists() {
var requestsLists = hostWeb.get_lists().getByTitle('Name'); // sharepoint list with all the request list urls.
context.load(requestsLists);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View></View>');
var items = requestsLists.getItems(camlQuery);
context.load(items, 'Include(URL)');
context.executeQueryAsync(onQuerySuccess, onQueryFail);
function onQuerySuccess(sender, args) {
var itemEnumerator = items.getEnumerator();
while (itemEnumerator.moveNext()) {
var promise = new Promise(function (resolve, reject) {
var item = itemEnumerator.get_current();
item = item.get_item('URL');
var itemUrl = item.get_description();
getRequestItemsFromList(itemUrl);
});
promises.push(promise);
}
console.log(promises);
Promise.all(promises).then(function (val) {
console.log(val);
execFuncs(); // not shown here
}).catch(function (response) {
console.log(response);
});
}
function onQueryFail(sender, args) {
alert("Request to retrieve list URL items has failed. " + args.get_message());
}
}
function getRequestItemsFromList(url) {
var lastPos = getSubstringIndex(url, "/", 4);
var webUrl = url.substring(0, lastPos); // truncates list url to parse out web url
var absListPos = getSubstringIndex(url, "AllItems.aspx", 1);
var absListUrl = url.substring(0, absListPos); // truncates the AllItems.aspx at the end of the list url
var relListPos = getSubstringIndex(absListUrl, "/", 3);
var relListUrl = absListUrl.substring(relListPos, absListUrl.length); // gets the list's relative url
var listName = "List Name";
console.log(webUrl);
execCrossDomainRequest(webUrl, listName, absListUrl);
}
function execCrossDomainRequest(webUrl, listName, absListUrl) {
var executor = new SP.RequestExecutor(appWebUrl);
executor.executeAsync({ // to collect the list description
url: appWebUrl + "/_api/SP.AppContextSite(@target)/web/lists/getbytitle(@name)?" +
"@target='" + webUrl + "'&@name='" + listName + "'" +
"&$select=Description",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: onCallSuccess,
error: onCallFail
});
function onCallSuccess(data) {
var json = JSON.parse(data.body);
var description = json.d.Description;
executor.executeAsync({ // to collect the list item information
url: appWebUrl + "/_api/SP.AppContextSite(@target)/web/lists/getbytitle(@name)/items?" +
"@target='" + webUrl + "'&@name='" + listName + "'" +
"&$top=500&$select=*," +
"Assigned_x0020_To/Title" +
"&$expand=Assigned_x0020_To/Id",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: onItemsCallSuccess,
error: onItemsCallFail
});
function onItemsCallSuccess(data) {
var itemsJson = JSON.parse(data.body);
var results = itemsJson.d.results;
cleanData(results, description, absListUrl);
}
function onItemsCallFail(data, errorCode, errorMessage) {
console.log("Could not make list items cross domain call. " + errorMessage);
}
}
function onCallFail(data, errorCode, errorMessage) {
console.log("Could not make list cross domain call. " + errorMessage);
}
}
function cleanData(results, listDescription, absListUrl) {
if (!results.length) {
return;
}
for (var i = 0; i < results.length; i++) {
var client = listDescription;
var id = results[i].ID;
...
}
var request = new Request(client, id, path, title, status, estimated, assignedTo, priority, description, response);
window.requests.push(request);
}
return Promise.resolve();
}
Нам нужно знать, какие вызовы вашей функции в вашем цикле являются асинхронными и как работает их соглашение о вызовах. Кроме того, обещания НЕ имеют никаких волшебных способностей знать, когда делаются асинхронные действия. Они знают только, выполняется ли операция async, если вы решите или отклоните обещание, когда операция async будет выполнена. Вместо этого обещания предоставляют всевозможные средства управления потоком и обработки ошибок для асинхронных операций, как только каждое обещание будет соответствующим образом установлено. Пожалуйста, опишите, что делают ВСЕ функции в вашем цикле, особенно асинхронные. – jfriend00
@ jfriend00 Я добавил в полный раздел задействованных функций. – LaLaLottie
Почему вы вызываете 'return Promise.resolve()' внутри 'cleanData' и что это должно делать? – DavidDomain