2016-03-31 13 views
6

Zgodnie z zaleceniami w dokumencie, przeniosłem jakiś długi kod do pobierania danych do natywnego modułu, aby zwolnić wątek JS, ale zauważam, że to nadal blokuje interfejs użytkownika. Dlaczego tak jest i co mogę zrobić, aby tego uniknąć?Dlaczego to wywołanie reaguje na macierzysty moduł, blokując interfejs użytkownika?

Moduł rodzimy jest wywoływana z JS jak tak:

MyNativeModule.fetch(path).then(data => dispatchData(data)) 

Sposób rodzimy wygląda następująco (używa Androida Firebase SDK):

@ReactMethod 
public void fetch(final String path, final Promise promise) { 
    root.child(path).addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot snapshot) { 
      if (snapshot.exists()) { 
       promise.resolve(castSnapshot(snapshot)); 
      } else { 
       promise.resolve(null); 
      } 
     } 
     @Override 
     public void onCancelled(FirebaseError firebaseError) { 
      promise.reject(firebaseError.getMessage()); 
     } 
    } 
} 

Sposób castSnapshot przekształca Firebase DataSnapshot obiekt do WriteableMap. Mogę udostępnić implementację, jeśli jest to przydatne.

Zauważyłem, że nawet jeśli zastąpię promise.resolve(castSnapshot(snapshot)); przez castSnapshot(snapshot); promise.resolve(null);, połączenie blokuje interfejs użytkownika: więc nie wysyła danych przez most, który jest winowajcą. Jeśli ilość danych jest duża, może zająć trochę czasu, a to wyraźnie blokuje.

Nawet jeśli ten kod jest długotrwały, to czy przeniesienie go do natywnego modułu nie powinno go uwolnić? Czego nie rozumiem?

Wielkie dzięki.

+1

mam ten sam problem. Myślałem, że rodzime moduły działają w innym wątku, ale wydaje się, że tak nie jest. –

+2

@RomShiri tak .. myślę, że jeśli chcemy korzystać z natywnych modułów z powodów perf, musimy zarządzać nawlekaniem siebie. Z dokumentacji: "Moduły rodzime nie powinny mieć żadnych założeń dotyczących tego, do jakiego wątku są wywoływane [...] Jeśli wymagane jest wywołanie blokujące, ciężka praca powinna zostać wysłana do wewnętrznie zarządzanego wątku roboczego, a wszelkie wywołania zwrotne od tam." – VonD

+0

Znalazłem to samo. Podejście Ryana było konieczne. – itinance

Odpowiedz

3

Spróbuj zawijania linii root.child w nowym przykład nici, tak:

@ReactMethod 
public void fetch(final String path, final Promise promise) { 
    new Thread(new Runnable() { 
     public void run() { 
      root.child(path)... 
     } 
    }).start(); 
} 
Powiązane problemy