如何“承诺”(或回调)此代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何“承诺”(或回调)此代码相关的知识,希望对你有一定的参考价值。

我的Sharepoint中有2个列表:演讲和学校。 在我的演讲形式中,我有一个学校的领域。我想从学校列表中使用值(姓名,地址,城市)自动填写此字段。 这是我的代码:

$(School_fieldID).autocomplete({
    minLength: 2,
    source: function (request, response) {
        var term = request.term.replace(/ /g, "*","*");
        var searchUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='and("*" + term + "*",path:"" + _spPageContextInfo.webAbsoluteUrl + "/Lists/Schools")'&enablefql=true";
        var executor = new SP.RequestExecutor(_spPageContextInfo.webAbsoluteUrl);

        executor.executeAsync({
            url: searchUrl,
            method: "GET",
            headers: { "Accept": "application/json; odata=verbose" },
            success: function (data) {
                var jsonObject = JSON.parse(data.body);
                var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
                var clientContext = new SP.ClientContext();
                var schoolList = clientContext.get_web().get_lists().getByTitle('Schools');

                response($.map(results, function (result) {
                    school = schoolList.getItemById(result.Cells.results[6].Value.split('=').pop());
                    clientContext.load(school, 'Title', 'Adress', 'City');
                    clientContext.executeQueryAsync(Function.createDelegate(this, function (schoolName, schoolAdress, schoolCity) {
                        schoolName = school.get_item('Title');
                        schoolAdress = school.get_item('Adress');
                        schoolCity = school.get_item('City');
                    }), Function.createDelegate(this, function (sender, args) {
                        alert('Error occured: ' + args.get_message());
                    }));
                    return {
                        label: schoolName + " (" + schoolAdress + " " + /*schoolCity + */ ")",
                        value: schoolName
                    };
                }));
            }
        });
    }
});

当我测试这段代码时,由于异步函数executeQueryAsync,schoolName,schoolAdress et schoolCity是未定义的。 所以我认为解决方案是在Promise或Callback中,但我尝试了一周不同的解决方案,但没有成功:-( 请注意我仔细阅读了这篇文章How do I return the response from an asynchronous call?,但无论如何都找不到一个好的解决方案...... 谁能帮我 ? 提前致谢, 弗洛朗

答案

考虑到你必须将一个对象数组传递给响应回调函数,并且每个结果都调用异步函数clientContext.executeQueryAsync,我们可以将它们中的每一个转换成一个promise并将它们传递给Promise.all(),它将等待所有他们要解决并归还他们。当它们都被解析后,对象将在schoolObjectArray中,然后你可以传递给响应函数。应该工作。

$(School_fieldID).autocomplete({
minLength: 2,
source: function (request, response) {
    var term = request.term.replace(/ /g, "*","*");
    var searchUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='and("*" + term + "*",path:"" + _spPageContextInfo.webAbsoluteUrl + "/Lists/Schools")'&enablefql=true";
    var executor = new SP.RequestExecutor(_spPageContextInfo.webAbsoluteUrl);

    executor.executeAsync({
        url: searchUrl,
        method: "GET",
        headers: { "Accept": "application/json; odata=verbose" },
        success: function (data) {
            var jsonObject = JSON.parse(data.body);
            var results = jsonObject.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
            var clientContext = new SP.ClientContext();
            var schoolList = clientContext.get_web().get_lists().getByTitle('Schools');

            Promise.all($.map(results, function (result) {
                school = schoolList.getItemById(result.Cells.results[6].Value.split('=').pop());
                clientContext.load(school, 'Title', 'Adress', 'City');
                return new Promise(function(resolve,reject) {
                    clientContext.executeQueryAsync(Function.createDelegate(this, function (schoolName, schoolAdress, schoolCity) {
                    schoolName = school.get_item('Title');
                    schoolAdress = school.get_item('Adress');
                    schoolCity = school.get_item('City');
                    resolve({
                            label: schoolName + " (" + schoolAdress + " " + /*schoolCity + */ ")",
                            value: schoolName
                        });
                    }), Function.createDelegate(this, function (sender, args) {
                        reject('Error occured: ' + args.get_message());
                    }));
                })
            }))
            .then(function(schoolObjectArray){
                response(schoolObjectArray)
            })
            .catch(console.error);
            }
        });
    }
});

以上是关于如何“承诺”(或回调)此代码的主要内容,如果未能解决你的问题,请参考以下文章

如何将我的代码从回调函数更改为承诺 [重复]

如何将回调转换为承诺? [复制]

Node.js 承诺、异步或只是回调

Node.js 从函数返回一个承诺

JavaScript - 返回承诺和/或调用回调?

等待多个承诺完成