Как выполнить несколько вызовов ajax перед запуском следующей цепной функции? - PullRequest
0 голосов
/ 23 мая 2019

Я могу получать электронные письма, имена пользователей и т. Д. Нескольких пользователей в элементе управления персоналом SharePoint. К сожалению, Id не является одним из доступных значений. Чтобы получить это, я предполагаю, что вам нужно выполнить несколько вызовов ajax, а в некоторых случаях вам необходимо убедиться, что эти вызовы завершены перед выполнением другой функции.

Я экспериментировал с вариантами when.done, when.apply.done и promises.all без удачи Я просто не делаю это правильно.

Вот как я заполняю массив писем из элемента управления выбора людей:

var ToCon = $("div[title='To Contacts'] > input").val();
var Fjson = JSON.parse(ToCon);
for (var i = 0; i < Fjson.length; i++) {
  EmailArray.push(Fjson[i].EntityData.Email);
}

Вот моя функция, чтобы получить идентификатор пользователя на основе их адреса электронной почты:

function GetUserId(X) {

        $.ajax({ 
            url: xhost + "/_api/web/SiteUsers?$select=Id&$filter=Email eq '" + X + "'",
            type: "GET", headers: { "Accept": "application/json;odata=verbose", }, //verbose
            success: function (data) {
                var xuserid = data.d.results[0].Id;
                return xuserid;
            },
            error: function (error) { alert(JSON.stringify(error)); }
        });
    }

Как мне вызвать функцию GetUserId (X) для каждого элемента в EmailArray, и убедиться, что она завершена, прежде чем перейти к другой связанной функции?

Ответы [ 4 ]

0 голосов
/ 27 мая 2019

Вы можете дождаться завершения всех обещаний, используя $ .when.apply, как вы упоминали.Вот синтаксис:

var promises = [];

promises.push(loadSomeData());
promises.push(loadMoreData());

$.when.apply($, promises)
.fail(function(err)  {
    console.log(err);

})
.done(function (result1, result2)  {
    console.log(result1);
    console.log(result2);
});

Обратите внимание, что в вызове done есть 2 аргумента, которые соответствуют числу обещаний, добавленных в массив.Первое обещание - это первый аргумент, второе обещание - это второй аргумент и т. Д.

Вот еще один способ получить пользователя с помощью JSOM:

function getUser(email) {
    var context = SP.ClientContext.get_current();
    var user = context.get_site().get_rootWeb().ensureUser(email);
    context.load(user);
    context.executeQueryAsync(function (sender, args) {
        console.log("Success: " + user.get_id());
    }, function (sender, args) {
        console.error(args.get_message());
    });
}
SP.SOD.executeOrDelayUntilScriptLoaded(function () {
    getUser("my@email.com");
}, "SP.js")

Кроме того, если вы хотителучший способ справиться со всеми этими обещаниями, взгляните на jQuery Deferred .Вы можете создавать свои собственные обещания и разрешать их после завершения вызовов.

function getUserAsPromise(email) {
    var deferred = $.Deferred();
    var context = SP.ClientContext.get_current();
    var user = context.get_site().get_rootWeb().ensureUser(email);
    this.context.load(user);
    this.context.executeQueryAsync(
        function (sender, args) {
            deferred.resolve(user);
        },
        function (sender, args) {
            deferred.reject(sender, args);
        }
    );
    return deferred.promise();
}
getUserAsPromise("my@email.com")
    .fail(function (sender, args) {
        console.error(args.get_message());
    })
    .done(function (user) {
        console.log("Success: " + user.get_id());
    });
0 голосов
/ 23 мая 2019

Я думаю, что вы ищете Promise.all () .

0 голосов
/ 24 мая 2019

Попробуйте приведенную ниже логику скрипта.

<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script type="text/javascript">
        function myClassA() {
            this.myAsynchronousMethod = function (arg) {
                return new Promise(function (resolve, reject) {
                    $.ajax({
                        url: _spPageContextInfo.webAbsoluteUrl + "/_api/web/SiteUsers?$select=Id&$filter=Email eq '" + arg + "'",
                        type: "GET", headers: { "Accept": "application/json;odata=verbose", }, //verbose
                        success: function (data) {
                            var xuserid = data.d.results[0].Id;
                            resolve(xuserid);
                        },
                        error: function (error) { reject(error); }
                    });
                });
            };
        }

        function main() {
            var testEmails = ["email", "email", "email"];
            var action = [];            
            for (var i = 0; i < testEmails.length; i++)
                action.push((new myClassA()).myAsynchronousMethod(testEmails[i]));

            Promise.all(action).then(function (response) {
                debugger;                
                for (i = 0; i < response.length; i++) {
                    //to do
                }                    
            });
        }
    </script>
    <input id="Button1" onclick="main();" type="button" value="button" />
0 голосов
/ 23 мая 2019

Один грязный способ - использовать «async: false» в вашем вызове ajax.это сделало бы запросы ajax синхронными.

Обещание также должно работать, если вы правильно его реализуете.используйте jQuery's Deferred для этого.

...