在启动下一个链接函数之前,如何完成多个ajax调用?

时间:2019-05-23 20:27:16

标签: ajax rest sharepoint promise .when

我可以在SharePoint人员选择器控件中获取多个用户的电子邮件,用户名等。不幸的是,Id不是可用值之一。为此,我假设您需要执行多个ajax调用,并且在某些情况下,您需要确保这些调用完成后才能执行其他功能。

我已经尝试了when.done,When.apply.done并保证所有的运气都没有。我只是做错了。

这是我从人员选择器控件中填充电子邮件数组的方式:

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);
}

这是我根据用户的电子邮件地址获取用户ID的功能:

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)); }
        });
    }

如何为EmailArray中的每个项目调用GetUserId(X)函数,并确保它在移至另一个链接函数之前完成?

4 个答案:

答案 0 :(得分:0)

一种肮脏的方法是在ajax调用中使用“ async:false”。 这将使ajax请求同步。

如果正确实现,承诺也应该起作用。 为此使用jQuery的Deferred。

答案 1 :(得分:0)

我认为您正在寻找Promise.all()

答案 2 :(得分:0)

尝试以下脚本逻辑。

<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" />

答案 3 :(得分:0)

您可以使用$ .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);
});

请注意,在完成的调用中,有2个参数,它们与您在数组中添加的Promise数量匹配。第一个承诺是第一个参数,第二个承诺是第二个参数,依此类推。

这是使用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());
    });