仍在努力抓住延迟

时间:2014-03-03 18:53:51

标签: javascript jquery

我的任务是从保存在Sharepoint 2013自定义列表中的记录创建可打印的公司目录。与网站中的其他页面一样,我通过REST功能访问列表的内容。

列表中有超过100条记录,SharePoint REST上有99项限制,我试图通过查询所有AM的列表然后再查询NZ,然后使用jquery的extend或merge来组合对象。

由于我必须考虑AJAX的异步陷阱,我正在尝试使用Deferred,我以为我终于抓住了但是没有......

这是我的jquery:

var printme = {
    init: function(){
        $('.ms-core-sideNavBox-removeLeftMargin').css('display', 'none');
        $('#contentBox').css('margin-left', '0' );
        $('#pageTitle').html("Corporate Directory -- Printable");

        var firstHalf = this.getFirstHalf();
        console.log(firstHalf);
    },
    getFirstHalf: function(){
        var dfd = new $.Deferred();

        $.ajax({
            url: "/humanresources/_api/web/lists/GetByTitle('Corporate Directory')/items?$filter=Title ge 'a' and Title lt 'n'&?orderby=Title asc",
            type: "GET",
            headers: { "accept" : "application/json;odata=verbose" },
            dataType: 'json',
            success: dfd.resolve
        });

        return dfd.promise();
    }
};
$(document).ready( function(){
    printme.init();
});

控制台日志不包含预期的43条记录,而是长度为1.我计划调用未来函数(getSecondHalf),然后合并2条响应并将其传递给Handlebars模板进行处理。这是console.log:

Object {state: function, always: function, then: function, promise: function, pipe: function…}
always: function () {
done: function () {
fail: function () {
pipe: function ( /* fnDone, fnFail, fnProgress */ ) {
progress: function () {
promise: function ( obj ) {
arguments: [Exception: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them]
get arguments: function ThrowTypeError() { [native code] }
set arguments: function ThrowTypeError() { [native code] }
caller: (...)
get caller: function ThrowTypeError() { [native code] }
set caller: function ThrowTypeError() { [native code] }
length: 1
name: ""
prototype: Object
__proto__: function Empty() {}
<function scope>
state: function () {
then: function ( /* fnDone, fnFail, fnProgress */ ) {
__proto__: Object

-UPDATE- 现在是我的jquery:

var printme = {
    init: function(){
        $('.ms-core-sideNavBox-removeLeftMargin').css('display', 'none');
        $('#contentBox').css('margin-left', '0' );
        $('#pageTitle').html("Corporate Directory -- Printable");

        var firstHalfDeferred = $.ajax({ 
            url: "/humanresources/_api/web/lists/GetByTitle('Corporate Directory')/items?$filter=Title ge 'a' and Title lt 'n'&?orderby=Title asc",
            type: "GET",
            headers: { "accept" : "application/json;odata=verbose" },
            dataType: 'json'
        });
        var secondHalfDeferred = $.ajax({
            url: "/humanresources/_api/web/lists/GetByTitle('Corporate Directory')/items?$filter=Title ge 'n' and Title lt 'z'&?orderby=Title asc",
            type: "GET",
            headers: { "accept" : "application/json;odata=verbose" },
            dataType: 'json'
        });

        $.when(firstHalfDeferred, secondHalfDeferred).done(function(firstHalf, secondHalf) {
            var result = $.extend({}, firstHalf[0], secondHalf[0]);

            Handlebars.registerHelper("formatPhone", function(Phone){
                phone = Phone.toString();
                return phone.substr(0,3) + '.' + phone.substr(3,3) + '.' + phone.substr(6,4);
            });

            var pcd_tmpl = $("#tmpl-corporate_print").html();
            var pcd_template = Handlebars.compile(pcd_tmpl);
            $('#print_pane').append( pcd_template(result) );

        }).fail(function(errorData) {
             console.log('Error: ' + errorType + ' with message: ' + errorMessage);
        });
    },
};

$(document).ready( function(){
    printme.init();
});

我的Handlebars模板是:

<div id="print_pane" style="float:left; width: 100%; padding:0 10px 0 40px;">
    <script id="tmpl-corporate_print" type="text/x-handlebars-template">
    <table cellpadding='5' cellspacing='10'>
        {{#each this}}
            <tr style="padding:10px;">
                <td style="width:120px;text-align:center;">
                <img alt="{{ Full_x0020_Name }}" src="/humanresources/CorporateFaces/{{ ImgName }}.png" />
                </td>
            <td>
                    <h1>{{ Full_x0020_Name }}</h1>
                    <h2>{{ JobTitle }}</h2>
                <h2>{{ Department }}</h2>
                <h3><b>{{formatPhone Phone}}</b></h3>
                </td>
            </tr>
        {{/each}}
    </table>
</script>
</div>

抛出错误:Uncaught TypeError:无法调用未定义的方法'toString'

这是因为我不知道如何访问数据元素,因为Phone(肯定在列表中)返回null。

这是一个返回值:

Object {d: Object}
d: Object
results: Array[53]
0: Object
AttachmentFiles: Object
Attachments: false
AuthorId: 2
Birthday: "11/21"
ContentType: Object
ContentTypeId: "0x0100533BA85B2C40D04B9578F78D81D2D12C"
CopyMana: null
CopyMana0: 5
Created: "2014-02-21T17:38:06Z"
Department: "Management Services (MSD)"
EditorId: 2
Email: "cripas@corporate.com"
Extension: "52587"
FieldValuesAsHtml: Object
FieldValuesAsText: Object
FieldValuesForEdit: Object
File: Object
FileSystemObjectType: 0
FirstName: "Christine"
FirstUniqueAncestorSecurableObject: Object
Folder: Object
Full_x0020_Name: "Christine Ripas"
GUID: "cdd3326b-fc1e-40f2-a070-aa00fb0c6598"
ID: 6
Id: 6
Img: Object
JobTitle: "Senior Vice President & COO"
MFN: "Randy Chairman"
ManagerId: 1
Modified: "2014-02-26T19:42:20Z"
OData__UIVersionString: "1.0"
ParentList: Object
Phone: "9015556767"
RoleAssignments: Object
Title: "Ripas"
__metadata: Object
__proto__: Object

2 个答案:

答案 0 :(得分:2)

您尝试做的事情是多余的,因为$ .ajax已经返回一个promise(延迟的子集)。你可以这样做:

var firstHalfDeferred = $.ajax({ /* settings for first half */});
var secondHalfDeferred = $.ajax({ /* settings for second half */});

$.when(firstHalfDeferred, secondHalfDeferred).done(function(firstHalf, secondHalf) {
   var result = $.extend({}, firstHalf[0], secondHalf[0]);

}).fail(function(errorData) {
   //take care of errors.
});

首先,你得到两个承诺。然后,$ .when()函数等待(实际上传递给它的任何数字)完成,或者任何一个都抛出错误。 done()方法将接受一个函数,该函数将接收与传递给$ .when的延迟一样多的参数。这些参数中的每一个都是一个数组,其中jQuery传递给AJAX成功处理程序的三个对象,因此arg [0]是数据。你只需混合收到的两个对象(这是因为你这么说,我不知道Sharepoint返回哪种数据)。

如果有任何失败,则执行fail()方法的参数。

答案 1 :(得分:1)

首先,$.ajax本身会返回一个承诺,因此无需手动创建承诺。你可以简单地return $.ajax

然而,问题是您正在检查的对象是承诺本身。当promise被解决后,该值将传递给您附加到它的.then().done()内的函数。

所以你想要:

firstHalf.done(function (value) {
  console.log(value);
});