일부 루프 내에서 루프 및 중첩 기능을 사용하여 약속을 사용하려고합니다. REST 호출에서 SharePoint 목록 항목을 가져 오는 일련의 함수가 있습니다. 일단 실행이 완료되면 다시 가져온 데이터를 사용하는 다른 함수가 호출됩니다.루프 및 중첩 된 기능으로 약속 사용
여러 개의 목록이 있고 각각에 여러 개의 목록 항목이 있기 때문에 각 REST 호출을 만들기 위해 while 루프를 사용했으며 거기에서 데이터 (목록 항목)가 개체에 넣어집니다. 이러한 객체는 배열에 배치되고 그 두 번째 함수는 계속 사용됩니다.
약속의 응답을받는 데 문제가 있습니다. 배열에 푸시 된 여러 약속을 가지고 생각한 다음 Promise.all
을 사용하여 then
을 사용하기 전에 모든 것이 해결되었는지 확인하십시오. 문제는 내가 resolve
을 올바로 반환하지 않기 때문에 모든 약속이 pending
인 채 유지된다는 것입니다. 아래를 봐주세요.
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);
});
}
이 포함 된 기능의 많은, 그래서이 실행 순서이기 때문에 : 나는 그 줄의 끝 이후 나는 Promise.resolve()
전화 낸 곳
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
마지막입니다.
어느 쪽이든 작동하지 않습니다. 다른 스레드를 체크 아웃했지만 라이브러리를 사용하지 않고이 작업을 수행하려고합니다. 미리 감사드립니다.
편집 :
전체 관련 코드 :
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();
}
루프에서 함수 호출이 비동기인지, 호출 규칙이 작동 하는지를 알아야합니다. 또한 약속에는 비동기적인 작업이 언제 완료되는지 알 수있는 마법의 힘이 없습니다. 그들은 비동기 작업이 완료 될 때 약속을 특별히 해결하거나 거절하는 경우에만 비동기 작업이 수행되는지 여부를 알 수 있습니다. 대신, 약속은 각 약속이 적절히 배관되면 비동기 작업을위한 모든 종류의 제어 흐름과 오류 처리 도구를 제공합니다. 루프의 모든 함수 호출, 특히 비동기 호출을 처리하고 있는지 문서화하십시오. – jfriend00
@ jfriend00 관련 함수의 전체 섹션에서 추가했습니다. – LaLaLottie
왜 cleanData에서'Promise.resolve()'를 호출하고 어떻게해야할까요? – DavidDomain