how to pass result of $.get to return of another function

时间:2015-05-24 21:36:05

标签: javascript jquery ajax promise

I have trouble with the callback of jquery $.get() ajax function.
I'm using the DataTables plugin and trying the "expanding row to see children details" example (can be seen here https://www.datatables.net/examples/api/row_details.html).

The problem is this line:
row.child( format(row.data()) ).show();
the function format() renders html direct rom the front end as can be seen:

function format ( d ) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
    '<tr>'+
        '<td>Full name:</td>'+
        '<td>'+d.name+'</td>'+
    '</tr>'+
    '<tr>'+
        '<td>Extension number:</td>'+
        '<td>'+d.extn+'</td>'+
    '</tr>'+
    '<tr>'+
        '<td>Extra info:</td>'+
        '<td>And any further details here (images etc)...</td>'+
    '</tr>'+
'</table>';
}

It uses data that is already on the table, and the DataTables has no example on how to do it the "server-side" way.

Here i use ajax as jquery deferred object, i need the format() to return the foo() result but it's not happening.

function foo(value)
{
    return $.get("<?php echo base_url()?>token/show?id="+value,null);
}


function format (id,callback) 
{
    callback(id).done(function(result) 
    {
         //I need the result to be returned but somehow it's broken
         return result;
     }).fail(function() 
     {
        alert('ajax error');
    });
}

It doesnt return the result, but if i do a console log it prints the entire view without any problem.
Here is where i call the function

var td = ('td :first-child',$(this))[0];
var id = $('div',td).attr('id');
oTable.fnOpen( nTr, format(id,foo), 'well hiddenRow' );

Is there a way using callbacks? or it's not possible?
Regards

1 个答案:

答案 0 :(得分:2)

您的数据提取程序foo()会返回一个承诺。无论您对数据做什么,只有在数据到达且承诺得到解决时才能完成。

您尝试的问题是,正如所写的那样,format()会返回undefined无法返回您想要的result。这就是异步的本质。最好的可能是返回foo()返回的承诺,但这对你没有好处,因为(如你所知)你想要一个结果,而不是你oTable.fnOpen(...)的结果承诺调用

解决方案是使用outide上的异步foo(...)和内部的oTable.fnOpen(...)将整个表达式内外翻。

最简单的形式是代码:

foo(id).then(function(result) {
    return oTable.fnOpen(nTr, result, 'well hiddenRow');
});

但是你还应该包括一些错误处理:

foo(id).then(function(result) {
    return oTable.fnOpen(nTr, result, 'well hiddenRow');
}, function(jqXHR, textStatus, errorThrown) {
    return errorThrown;
});

并且,假设此代码本身位于某个外部函数中,那么您应该返回整个链生成的承诺。

function open(id, nTr) {
    return foo(id).then(function(result) {
        return oTable.fnOpen(nTr, result, 'well hiddenRow');
    }, function(jqXHR, textStatus, errorThrown) {
        return errorThrown;
    });
}

反过来,这将允许对open()流程的成功/失败采取适当的行动。

open(id, nTr).then(function(rowNode) {
    //foo() returned a result and oTable.fnOpen() was called. 
}).fail(function(error) {
    //Something went wrong.
    console.log(error);
});