2016-06-09 16 views
10

Tôi đang triển khai Pusher vào ứng dụng React + Redux Saga của mình, nhưng tôi gặp một số vấn đề với một số cuộc gọi lại nơi tôi không thể nhấn phương thức put(...). Sử dụng console.log(...) v.v. trong các phương pháp hiển thị, nhưng tôi không thể put đến trạng thái đơn đăng ký của mình.Sử dụng đặt bên trong gọi lại hàm ẩn danh

Tôi có thể sai về một số việc triển khai các chức năng không đồng bộ/máy phát, nhưng hiện tại tôi đang gặp nhiều khó khăn.

Mã của tôi để minh họa cho những gì sẽ không cháy:

import { takeLatest } from 'redux-saga' 
import { call, put } from 'redux-saga/effects' 

// Pusher actions 
export const pusherConnecting =() => { 
    return { 
     type: ActionTypes.PUSHER_CONNECTING 
    } 
}; 

export const pusherConnectSucceeded = (client) => { 
    return { 
     type: ActionTypes.PUSHER_CONNECT_SUCCEEDED, 
     client: client 
    } 
}; 

const pusherConnectFailed = (exception) => { 
    return { 
     type: ActionTypes.PUSHER_CONNECT_FAILED, 
     message: exception 
    } 
}; 

// Pusher Saga 
function * connectPusher(action) { 
    try { 
     const pusher = yield call(Api.connectPusher, action.directory, function(subscription) { 
      subscription.bind(PUSHER_BIND_RELOAD, function() { 
       location.reload(true); 
      }); 

      subscription.bind(PUSHER_BIND_REQUEST_DATA, function(data) { 
       if (data) { 
        put(updateDirectory(data)); 
       } else { 
        put(requestDirectory(action.directory.id)); 
       } 
      }); 
     }); 

     pusher.connection.bind('connected', function() { 
      put(pusherConnectSucceeded(pusher)); 
     }); 

     yield put(pusherConnecting()); 

    } catch (e) { 
     yield put(pusherConnectFailed(e)); 
    } 
} 

export default function * pusherSaga() { 
    yield * takeLatest(ActionTypes.DIRECTORY_FETCH_SUCCEEDED, connectPusher); 
} 



// My Api.ConnectPusher 
export function * connectPusher(directory, subscription) { 
    var pusher = new Pusher(PUSHER_KEY, { 
     encrypted: true 
    }); 

    var channels = ["test1", "test2" ]; 

    for (var i = 0; i < channels.length; i++) { 
     // Take each channel and callback with the subscription 
     yield subscription(pusher.subscribe(channels[i])); 
    } 

    return pusher; 
} 

Giải pháp dựa trên @Sebastien

yield put(yield onConnect(pusher)); 

function onConnect(pusher) { 
    return new Promise((resolve, reject) => { 
     pusher.connection.bind('connected', function() { 
      resolve(pusherConnectSucceeded(pusher)); 
     }); 
    }); 
} 
+0

"Không được nhấn" nghĩa là gì? Bạn không đạt được dòng đó? Làm thế nào bạn kiểm tra, với một trình gỡ lỗi? –

+0

Điều đó có nghĩa là tôi không thể kích hoạt phương pháp này. 'Put'method không được gọi trong lời gọi lại phương thức nặc danh của tôi. Hoặc có thể là vậy, nhưng tiểu bang không thay đổi (đó là câu hỏi của tôi). – janhartmann

+0

Tại sao "có thể"? Có vẻ như đó sẽ là một điều cơ bản ** thực sự ** để xác định, cho dù 'đặt' không đạt được hay đạt được nhưng không có hiệu quả mong muốn. Tôi muốn sử dụng một trình gỡ lỗi để làm theo những gì, chính xác, xảy ra, hoặc (và điều này là ** rất nhiều ** một tùy chọn hạng hai) ném vào một số 'console.log' s. (Nhưng so với việc lang thang với ngọn đuốc 'console.log', sử dụng trình gỡ lỗi giống như bật đèn.) –

Trả lời

6

Redux-saga không cho phép để put mà không sử dụng từ khóa yield. Việc đặt tạo ra một đối tượng/hiệu ứng json đơn giản mà phải được diễn giải/thực hiện và sẽ không xảy ra nếu bạn không tạo ra.

Ngoài ra, ngay cả với yield put(...), nếu điều này được thực hiện trong một cuộc gọi lại, nó sẽ không được giải thích, bởi vì Redux-saga không có khả năng chạy callbacks trong trình thông dịch của nó. Chúng đơn giản sẽ được chạy như những cuộc gọi lại bình thường và không có gì sẽ xảy ra.

Nếu subscription.bind được cho là trả lại một kết quả duy nhất, bạn có thể thay thế cuộc gọi đó thành một hàm trả về lời hứa và sau đó đưa ra lời hứa đó.

Nếu subscription.bind được cho là trả lại luồng kết quả, bạn có thể cần thay vì tạo một channel. Tôi đoán trong tương lai, một người nào đó sẽ chuyển một thứ gì đó có thể dễ dàng cho phép chuyển đổi Quan sát thành các luồng Redux-saga

Lưu ý rằng nếu bạn không cần hủy đăng ký/đăng ký nhiều lần, bạn có thể đơn giản hơn để đặt mã này bên ngoài câu chuyện và chỉ cần thực hiện

 subscription.bind(PUSHER_BIND_RELOAD, function() { 
      location.reload(true); 
     }); 

     subscription.bind(PUSHER_BIND_REQUEST_DATA, function(data) { 
      if (data) { 
       reduxStore.dispatch(updateDirectory(data)); 
      } else { 
       reduxStore.dispatch((requestDirectory(action.directory.id)); 
      } 
     }); 
+0

** NÀY ** là những gì tôi cần biết. Tôi sẽ làm việc ra một giải pháp và cập nhật câu trả lời của tôi với một giải pháp. Cảm ơn rất nhiều! – janhartmann

+0

bạn có thể cung cấp một ví dụ đơn giản về "Nếu subscription.bind có nghĩa vụ trả về một kết quả duy nhất, bạn có thể thay thế cuộc gọi đó thành một hàm trả về một lời hứa, và sau đó mang lại lời hứa đó"? – janhartmann

+0

Cập nhật câu hỏi của tôi với giải pháp của tôi, bạn nghĩ rằng điều này là đủ tốt? – janhartmann

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