2013-05-16 69 views
18

Làm thế nào tôi có thể làm công việc nàyNode.js async để đồng bộ hóa

var asyncToSync = syncFunc(); 

function syncFunc() { 
    var sync = true; 
    var data = null; 
    query(params, function(result){ 
     data = result; 
     sync = false; 
    }); 
    while(sync) {} 
    return data; 
} 

tôi đã cố gắng để có được chức năng đồng bộ hóa từ async một, tôi cần nó để sử dụng freetds truy vấn async như đồng bộ hóa một

+4

Async callbacks luôn chạy sau khi chức năng ngăn xếp đã bị xóa. Do đó, không thể trả lại kết quả ansyc một cách đồng bộ. Bất kỳ chức năng đồng bộ nào bắt đầu một hành động không đồng bộ phải nhất thiết phải trả lại trước khi hành động async bắt đầu. ** Thay vào đó **, bạn muốn làm cho hàm bên ngoài của bạn * cũng * không đồng bộ bằng cách chấp nhận một cuộc gọi lại được gọi bên trong hàm gọi lại đến 'truy vấn'. – apsillers

+1

Chức năng truy vấn có thực hiện cuộc gọi cơ sở dữ liệu không? Nếu vậy, máy khách DB có thể cung cấp phiên bản đồng bộ của hàm truy vấn đó. – helpermethod

+0

Nhân bản: [Cách chặn các hàm không đồng bộ trong JavaScript] (http://stackoverflow.com/questions/4345945/how-to-block-on-asynchronous-functions-in-javascript) (nhưng không có nhiều câu trả lời giải thích tốt) – apsillers

Trả lời

12

Sử dụng deasync - mô-đun được viết bằng C++ hiển thị vòng lặp sự kiện Node.js thành JavaScript. Mô-đun này cũng hiển thị hàm sleep chặn mã tiếp theo nhưng không chặn toàn bộ chuỗi, cũng như không phải chờ đợi quá lâu. Bạn có thể đặt các sleep chức năng trong while vòng lặp của bạn:

var asyncToSync = syncFunc(); 

function syncFunc() { 
    var sync = true; 
    var data = null; 
    query(params, function(result){ 
     data = result; 
     sync = false; 
    }); 
    while(sync) {require('deasync').sleep(100);} 
    return data; 
} 
+1

Đây là phần duy nhất mà bạn không phải chạy bên trong một sợi (mà bạn không thể luôn luôn làm nếu bạn không kiểm soát mã gọi) – tmandry

+0

TUYỆT VỜI !!! Tôi thích deasync – Aminadav

+0

Thật vậy! Đây là người duy nhất làm việc với vụ án của tôi. Cảm ơn! – yoshi

9

Bạn có thể làm điều đó với Thông báo node-sync lib

var sync = require('sync'); 

sync(function(){ 
    var result = query.sync(query, params); 
    // result can be used immediately 
}) 

: truy vấn của bạn phải sử dụng cuộc gọi standart callback (với lỗi đầu tiên): callback (lỗi, kết quả). Nếu bạn không thể thay đổi phương thức truy vấn, chỉ cần tạo .async() wrapper (xem liên kết github).

+1

Tôi có chức năng async với callback err và resutls, là "sync (function() {})" có thể trả về giá trị trong chức năng đồng bộ js bình thường không? – user840250

+0

No. sync() chỉ là bối cảnh chủ đề mới. Nó không retun bất cứ điều gì. Chỉ cần bọc tất cả các mã của nó và bạn có thể sử dụng .sync trên các chức năng async. –

3

Tôi đã sử dụng syncrhonize.js với thành công lớn. Thậm chí có một yêu cầu kéo đang chờ xử lý (hoạt động khá tốt) để hỗ trợ các hàm async có nhiều tham số. Tốt hơn và dễ sử dụng hơn so với nút đồng bộ hóa imho. Thêm tiền thưởng mà nó có tài liệu dễ hiểu và kỹ lưỡng, trong khi nút đồng bộ thì không.

1

Sự cố bạn đang gặp phải là vòng lặp chặt chẽ trong khi đang chặn. Vì vậy, tôi không nghĩ rằng gọi lại truy vấn của bạn sẽ bao giờ được chạy. Tôi nghĩ rằng bạn cần phải sử dụng setTimeout hoặc tương tự để ngăn chặn chức năng chặn, nhưng bạn nên làm như vậy, chức năng sẽ trở lại trước khi gọi lại được gọi. Chức năng này phải được thực hiện ở mức thấp hơn.

Nếu bạn đang ở trong trình duyệt, bạn có thể xem this article. Trong nút bạn phải dựa vào việc thực hiện bất cứ điều gì bạn đang truy vấn. Nó có thể hoặc không thể cung cấp các phương thức đồng bộ.

7

Ngày nay mô hình máy phát điện này có thể là một giải pháp tuyệt vời trong nhiều tình huống:

// nodejs script doing sequential prompts using async readline.question function 

var main = (function*() { 

    // just import and initialize 'readline' in nodejs 
    var r = require('readline') 
    var rl = r.createInterface({input: process.stdin, output: process.stdout }) 

    // magic here, the callback is the iterator.next 
    var answerA = yield rl.question('do you want this? ', res=>main.next(res))  

    // and again, in a sync fashion 
    var answerB = yield rl.question('are you sure? ', res=>main.next(res))   

    // readline boilerplate 
    rl.close() 

    console.log(answerA, answerB) 

})() // <-- executed: iterator created from generator 
main.next()  // kick off the iterator, 
       // runs until the first 'yield', including rightmost code 
       // and waits until another main.next() happens 
Các vấn đề liên quan