簡體   English   中英

JQuery / Javascript內聯回調

[英]JQuery / Javascript inline callback

在龍卷風我們有gen模塊,它允許我們編寫這樣的結構:

def my_async_function(callback): 
    return callback(1)

@gen.engine 
def get(self): 
    result = yield gen.Task(my_async_function) #Calls async function and puts result into result variable 
    self.write(result) #Outputs result

我們在jquery或其他javascript庫中有相同的語法糖嗎?

我想要這樣的東西:

function get_remote_variable(name) { 
    val = $.sweetget('/remote/url/', {}); //sweetget automatically gets callback which passes data to val
    return val
}

1.8之前的jQuery版本支持通過async: false設置同步ajax調用 它是一個有限制的黑客(沒有跨域或jsonp,鎖定瀏覽器),如果可能的話我會避免它。

有幾個可用的庫為Javascript中的異步操作提供了一些語法糖。 例如:

...但是我認為沒有任何東西可以提供您正在尋找的同步語法 - 由於JavaScript在瀏覽器中的工作方式,因此總會涉及回調。

您將該函數描述為“my_async_function”,但您使用它的方式是同步而不是異步

您的示例代碼需要阻止 - 如果“my_async_function”是真正的異步(非阻塞),則在您調用“my_async_function”之后,將立即執行以下代碼行self.write(result) 如果函數需要任何時間(我的意思是任何時間 )來返回一個值,那么self.write(result)最終會寫什么? 也就是說,如果在result有值之前執行self.write(result) ,則不會得到預期的結果。 因此,“my_async_function”必須阻塞,它必須在前進之前等待返回值,因此它不是異步的。

具體到你的問題, $.sweetget('/remote/url/', {}) :為了實現這一點,你必須能夠阻止,直到ajax請求(這本質上是異步的 - 它放入AJAX中的第一個A回來了。

您可以通過延遲sweetget的返回來破解同步調用,直到XHR狀態發生變化,但是您將使用while循環(或類似的東西)並冒險阻止瀏覽器UI線程或設置其中一個“此腳本是花了太長時間“警告。 Javascript不提供線程控制。 您無法指定當前線程正在等待,因此請繼續執行其他操作一分鍾。 您也可以通過手動測試超時閾值來應對這種情況。

到現在為止,人們應該開始懷疑:為什么不使用回調呢? 無論你如何切片,Javascript都是單線程的。 沒有sleep ,沒有thread.sleep 這意味着任何同步代碼都將阻止UI。

在這里,我嘲笑了大概看起來像是什么樣的sweetget 正如你所看到的,您的瀏覽器線程將作為執行進入從緊,一旦鎖定while循環。 實際上,在我的計算機上,ajax請求甚至不會觸發,直到瀏覽器顯示無響應的腳本對話框。

// warning: this code WILL lock your browser!
var sweetget = function (url, time_out) {
    var completed = false;
    var result = null;
    var run_time = false;
    if (time_out)
        run_time = new Date().getTime();

    $.ajax({
        url: url,
        success: function(data) {
            result = data;
            completed = true;
        },
        error: function () {
           completed = true;
        }
    });                    // <---- that AJAX request was non-blocking

    while (!completed) {  // <------ but this while loop will block
        if (time_out) {
            if (time_out>= run_time)
                break;
            run_time = new Date().getTime();
        }
    }
    return result;
};

var t = sweetget('/echo/json/');
console.log('here is t: ', t);

試一試: http//jsfiddle.net/AjRy6/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM