2012-08-29 35 views
6

Trong mã của tôi, tôi có một loạt các cuộc gọi chức năng. Tôi lặp lại các cuộc gọi này và sử dụng .apply() để gọi cho họ. Vấn đề là nếu cuộc gọi của hàm mới mất bất kỳ loại thời gian nào, vòng lặp sẽ .apply() và gọi hàm tiếp theo trước khi hàm trước kết thúc. >. < Dưới đây là một ví dụ:Tôi làm cách nào để thêm gọi lại vào phương thức .apply()?

function someFunc(element, calls){ 
    if(calls.length){ 
    fn = calls[0]; 
    calls.shift(); 
    fn.apply(element, args); 
    someFunc(element, calls); 
    } 
} 

Vì vậy, nếu có một callback trên áp dụng chức năng này sau đó có thể làm việc như thế nào tôi muốn nó. tức là

function someFunc(element, calls){ 
    if(calls.length){ 
    fn = calls[0]; 
    calls.shift(); 
    fn.apply(element, args, function(){ 
     someFunc(element, calls); 
    }); 
    } 
} 

Tôi cũng có câu hỏi về cách gọi hàm someFunc bên trong chức năng gọi lại. Các hàm trong mảng calls của tôi ảnh hưởng đến biến số element của tôi. Vì vậy, tôi muốn chắc chắn rằng sau khi nó được thay đổi, nó được chuyển tới someFunc trong hàm gọi lại để hàm tiếp theo có thể thao tác nó. Đôi khi tôi chỉ bị lẫn lộn với bối cảnh this. :)

Nếu nó giúp, tôi đang sử dụng jQuery. Tôi biết làm thế nào để thêm callbacks cho các phương thức jQuery nhưng tôi không biết làm thế nào để làm điều đó khi tôi đang đối phó với mã JavaScript gốc. Tôi làm cách nào để thêm gọi lại vào phương thức .apply()?

+1

Không có cách nào để làm những gì bạn muốn trừ khi bạn biết một mẫu tham số mà tất cả các chức năng của bạn theo dõi. – Pointy

+0

@Pointy - Tại sao tôi cần một mẫu tham số nếu tôi đặt tất cả các tham số của mình trong một mảng hay còn gọi là 'args'? – Aust

+0

Vấn đề là không có cách nào để cho biết liệu một hàm không đồng bộ và được thiết kế để chấp nhận tham số hàm gọi lại (hoặc hai tham số như vậy hay nhiều hơn). Bạn không thể làm cho hệ thống "chờ" cho một hàm và theo dõi không đồng bộ của nó để kết thúc. Vì vậy, nếu bạn * biết * rằng tất cả các hàm của bạn (ví dụ) lấy một cuộc gọi lại làm tham số cuối cùng, thì bạn có thể làm việc gì đó. – Pointy

Trả lời

2

Đảm bảo rằng mọi chức năng bạn gọi đều trả về promise. Sau đó bạn có thể "chờ" cho lời hứa đó để được "giải quyết" trước khi tiếp tục với chức năng tiếp theo trong danh sách của bạn:

function someFunc(element, calls) { 
    if (calls.length) { 
     var fn = calls.shift(); 
     fn.apply(element, args).done(function(el) { // what's args? 
      el = el || element; // default to previous element if necessary 
      someFunc(el, calls); 
     }); 
    } 
} 

với mỗi chức năng tìm kiếm cái gì đó như:

function myFunc1(el) { 
    var def = $.Deferred(); 

    // do something async, and "resolve" the deferred object in the async callback 
    ...(function() { 
     def.resolve(el); // this "el" will get passed to the next function 
    }); 

    return def.promise(); 
} 

Nếu nhiệm vụ không đồng bộ là một cuộc gọi AJAX bạn chỉ có thể trả về kết quả jqXHR trực tiếp thay vì tạo một đối tượng trì hoãn mới.

+0

Nếu một số hàm tôi chuyển vào biến 'calls' không phải của tôi, thì tôi sẽ thêm' $ như thế nào.Đối tượng hoãn() '? Tôi có thể bọc nó trong một chức năng khác, hoặc là thậm chí có thể? – Aust

+0

Có, bạn có thể bọc các chức năng, nhưng _somehow_ bạn vẫn phải 'giải quyết' lời hứa và điều đó phải được thực hiện trong cuộc gọi lại không đồng bộ. – Alnitak

+0

Vì vậy, ngay cả khi tôi quấn nó, tôi trở lại vấn đề ban đầu mà @Pointy đã đưa lên? Đó là, nếu một hàm không có một cuộc gọi lại, thì điều tôi muốn là không thể? – Aust

Các vấn đề liên quan