React-native: Unterstützung für AlarmManager in Timing hinzufügen, um die ordnungsgemäße Handhabung von langen Timern zu ermöglichen

Erstellt am 16. März 2017  ·  173Kommentare  ·  Quelle: facebook/react-native

Das Einstellen von Timern für mehrere Minuten wird in React Native unter Android nicht richtig gehandhabt: Es hält das Timing-Modul wach, anstatt sich darauf zu verlassen, dass das System uns aufweckt, wenn der Timer abläuft.

Wir sollten untersuchen, wie ein Cut-Off festgelegt wird, bei dem wir an AlarmManager und Handler.postDelayed delegieren, anstatt die Timer mit Framecallbacks zu behandeln.

Bug JavaScript Android

Hilfreichster Kommentar

@ skv-headless Stellungnahme eingehend. :) :)

Meiner Meinung nach muss diese Einstellung zu Problemen verschwinden. Ich habe gesehen, dass es öfter auftaucht und die Leute Warnungen ignorieren. Das sind Warnungen. Sie warnen dich. Ignoriere sie nicht, tu etwas. Ich habe Apps gesehen, bei denen alle Warnungen einfach ignoriert werden, sogar Verfallsbenachrichtigungen. Dann bricht Ihre App und Sie fragen sich, warum.

In diesem Fall können Sie diese Zeitüberschreitungen konfigurieren und verringern oder einen anderen Ansatz für den Umgang mit ihnen festlegen. Vielleicht stupsen Sie sogar die Betreuer der Bibliotheken an und bitten sie, bei der Erarbeitung einer Lösung zu helfen.

Mein Rat ist, diesem Thread zu folgen, bis jemand, der klug ist, eine tatsächliche Lösung findet, damit Sie sich dann mit dieser Antwort vertraut machen können. Und dann ignorieren Sie vielleicht in der Zwischenzeit (wenn Sie das Problem nicht lösen können / wollen) die Warnungen.

TL; DR;

Ja, Sie können die Warnungen vorübergehend ignorieren. Checken Sie einfach ab und zu ein, um zu sehen, wie der Status ist und ob Maßnahmen erforderlich sind.

Alle 173 Kommentare

Große Verbesserung!

Dies würde bei socket.io helfen, das standardmäßig einen Timer von 85000ms behält. Auf dem RN-Master beträgt der Schwellenwert 60000ms .

Und Firebase, die auch lange Timer verwendet.

Ich erhalte folgende Warnung, wenn ich die Firebase-Bibliothek verwende

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 111862ms)

Wie man diese Warnung loswird ...

Ich erhalte folgende Warnung, wenn ich auch die Firebase-Bibliothek verwende. Weiß jemand, wie man dieses Problem löst?

Ich bekomme diese Warnung auch mit Firebase.

"firebase": "^3.9.0",
"react-native": "0.44.0"

Gleiches Problem ( 85000ms ), jedoch ohne firebase . Meine Paketliste:

  "dependencies": {
    "apisauce": "0.11.0",
    "format-json": "1.0.3",
    "lodash": "4.17.4",
    "markdown-it": "^8.3.1",
    "native-base": "^2.1.3",
    "normalizr": "^3.2.2",
    "prop-types": "^15.5.10",
    "querystringify": "1.0.0",
    "ramda": "0.23.0",
    "react": "16.0.0-alpha.6",
    "react-markdown": "^2.5.0",
    "react-native": "0.44.0",
    "react-native-animatable": "1.2.0",
    "react-native-config": "0.4.2",
    "react-native-device-info": "0.10.2",
    "react-native-drawer": "2.3.0",
    "react-native-htmlview": "0.9.0",
    "react-native-i18n": "1.0.0",
    "react-native-linear-gradient": "^2.0.0",
    "react-native-photo-view": "^1.2.0",
    "react-native-router-flux": "3.39.1",
    "react-native-scrollable-tab-view": "*",
    "react-native-share": "^1.0.20",
    "react-native-vector-icons": "4.1.1",
    "react-navigation": "^1.0.0-beta.9",
    "react-redux": "5.0.4",
    "redux": "3.6.0",
    "redux-persist": "4.6.0",
    "redux-saga": "0.15.3",
    "reduxsauce": "0.4.1",
    "seamless-immutable": "7.1.2"
  },
  "devDependencies": {
    "ava": "^0.18.2",
    "babel-eslint": "^7.1.1",
    "babel-preset-es2015": "^6.18.0",
    "enzyme": "^2.6.0",
    "husky": "^0.13.1",
    "ignite-animatable": "^0.3.1",
    "ignite-dev-screens": "^2.0.0-beta.9",
    "ignite-i18n": "^0.1.1",
    "ignite-ir-boilerplate-2016": "^0.2.2",
    "ignite-vector-icons": "^0.2.1",
    "mockery": "^2.0.0",
    "nyc": "^10.1.2",
    "react-addons-test-utils": "^15.3.1",
    "react-dom": "^15.4.0",
    "react-native-mock": "^0.3.1",
    "reactotron-apisauce": "^1.7.0",
    "reactotron-react-native": "^1.7.0",
    "reactotron-redux": "^1.7.0",
    "reactotron-redux-saga": "^1.7.0",
    "snazzy": "^6.0.0",
    "standard": "^8.6.0"
  }

Ich habe ein ähnliches Problem mit 0.44.0 unter Android. Ich benutze auch keine Firebase:

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 85000ms)

Hallo Leute, habe mich gefragt, ob es dafür eine schnelle Lösung gibt. Ich benutze:

react-native 0.44 react 16.0.0-alpha.6 feathers-socketio 1.6.0

Es ist sehr ärgerlich, wenn ich während der Entwicklung herausspringe. Kann ich die Warnung vorerst verbergen?

Gleiches Problem hier mit Firebase 3.9.0

Wenn es Sie stört, fügen Sie einfach console.ignoredYellowBox = ['Setting a timer'];

@ skv-headless Stellungnahme eingehend. :) :)

Meiner Meinung nach muss diese Einstellung zu Problemen verschwinden. Ich habe gesehen, dass es öfter auftaucht und die Leute Warnungen ignorieren. Das sind Warnungen. Sie warnen dich. Ignoriere sie nicht, tu etwas. Ich habe Apps gesehen, bei denen alle Warnungen einfach ignoriert werden, sogar Verfallsbenachrichtigungen. Dann bricht Ihre App und Sie fragen sich, warum.

In diesem Fall können Sie diese Zeitüberschreitungen konfigurieren und verringern oder einen anderen Ansatz für den Umgang mit ihnen festlegen. Vielleicht stupsen Sie sogar die Betreuer der Bibliotheken an und bitten sie, bei der Erarbeitung einer Lösung zu helfen.

Mein Rat ist, diesem Thread zu folgen, bis jemand, der klug ist, eine tatsächliche Lösung findet, damit Sie sich dann mit dieser Antwort vertraut machen können. Und dann ignorieren Sie vielleicht in der Zwischenzeit (wenn Sie das Problem nicht lösen können / wollen) die Warnungen.

TL; DR;

Ja, Sie können die Warnungen vorübergehend ignorieren. Checken Sie einfach ab und zu ein, um zu sehen, wie der Status ist und ob Maßnahmen erforderlich sind.

@imamatory Ich denke, ist von Rectotron

Ich denke, ist von Rectotron

In diesem Fall kann diese Warnung einfach ignoriert werden.
... aber mein Android Emulator wird manchmal langsam, vielleicht ist es einer der Gründe.

@imamatory Ich hoffe, die wirkliche Lösung ist genauso einfach

Hallo, ich denke ich habe die Lösung gefunden:
Zunächst müssen Sie die folgende Datei in Ihrem Projekt finden: Bibliotheken / Core / Timer / JSTimer; js
Öffnen Sie es und Sie müssen nur diese Konstante ändern. MAX_TIMER_DURATION_MS, um Ihre Dauer zu erhöhen, wurde am Ende der Warnung geschrieben!

@nicolasZZ Hallo, danke für die Lösung. Aber ist das eine gute Vorgehensweise, um die JSTimer -Bibliothek anstelle unseres eigenen Codes zu ändern?

@nicolasZZ @AmroAly In meinen Augen ist diese Lösung keine gute Vorgehensweise, da sie sehr instabil ist. Am besten ignorieren Sie die Warnung, während die offizielle Lösung veröffentlicht wird.

console.ignoredYellowBox = [
    'Setting a timer'
]

Die Lösung von @ skv-headless ist gut, funktioniert aber in meinem Fall nur mit "Enter" zwischen den Klammern

@rigobcastro Danke, dass die nervigen Warnungen versteckt.

@ DZuz14 Es wäre fantastisch, wenn Sie eine PR senden oder zumindest das Gespräch beginnen könnten. Danke 👍

hi ~
Ich habe socket.io benutzt. nodejs and RN44 or RN 45
Ich habe diese Timer gewarnt.

Ich habe diese Lösung gefunden
reference reactotron PR

Personal Server NodeJS und scoket.io

const express = require('express')
const app = express()
const server = require('http').Server(app)
const io = require('socket.io')(server, {pingTimeout: 30000})

Vielen Dank!

Ich habe ein einfaches React Native-Projekt für Android und verwende Firebase Auth mit React Native für Login und Signup, aber ich habe den gelben Fehler: Was soll ich tun? Link meiner Frage in stackoverslow (https://stackoverflow.com/questions/44603362/setting-a-timer-for-a-long-period-of-time-ie-multiple-minutes)

Vielen Dank an DZuz14
Ich habe diesen Fehler erhalten, wenn ich react-native run-android ausführe

D:\Projects 2016\Web\Android\mohajerkade-android\android\app\src\main\java\com\mohajerkade\AlarmManagerModule.java:40: error: cannot find symbol
       Intent intent = new Intent(context, AlarmReceiver.class);
                                           ^
  symbol:   class AlarmReceiver
  location: class AlarmManagerModule
1 error
:app:compileDebugJavaWithJavac FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugJavaWithJavac'.
> Compilation failed; see the compiler error output for details.

Ich möchte Firebase Auth mit React Native für Login und Signup verwenden, aber ich habe diesen gelben Fehler erhalten.
1: Was genau ist dieses Modul?
2: Warum braucht mein Projekt dieses Modul?

Ich habe über diesen Link nach Stackoverflow gefragt: (https://stackoverflow.com/questions/44603362/setting-a-timer-for-a-long-period-of-time-ie-multiple-minutes)
Ich habe mich über diesen Link beim Google Firebase-Team gemeldet: (https://github.com/firebase/firebase-js-sdk/issues/97)

@ DZuz14 Ich habe die gleiche Frage wie @saeedhei .

Grundsätzlich verwenden wir das Knotenmodul firebase , das diese Zeitgeber für lange Zeiträume verwendet.

Das Hinzufügen Ihres Moduls reicht wohl nicht aus. Wir müssen den Code innerhalb des Knotenmoduls firebase neu schreiben, um Ihre Alarme anstelle von Javascript-Timern zu verwenden, oder?

Danke @ DZuz14

Wenn Sie sich also das npm-Paket mit dem Namen firebase ansehen, werden Sie feststellen, dass es an vielen Stellen setTimeout verwendet. Dies ist in Ordnung, da die Bibliothek für Websites und node.js-Server geschrieben wurde. react-native ist eine Art node.js-Server, läuft jedoch auf einem Telefon - und wie die Warnung richtig zeigt - sind lang laufende Javascript-Timer in dieser Umgebung nicht gut und können den Akku entladen und andere unerwünschte Nebenwirkungen haben .

Ich denke, wir müssen die Firebase-Leute davon überzeugen, tatsächlich zu Ihrem Ansatz zu wechseln und ein Paket zu verteilen, das speziell für react-native .

@BerndWessels https://www.npmjs.com/package/react-native-firebase Haben Sie sich das angesehen? Sagt, dass Firebase auf dem nativen Thread ausgeführt werden kann. Ich bin mir nicht sicher, wie wahr das ist, könnte aber einen Blick wert sein. Sie könnten das sogar benutzen, ich bin mir nicht sicher.

@ DZuz14 Danke, ich werde das überprüfen.

console.ignoredYellowBox = [
'Timer einstellen'
]]

@rigobcastro Wo kann ich diesen Code

@ Jazz747 Oben in Ihrer Setup-Datei zum Beispiel app.js, index.android.js oder index.ios.js

console.ignoredYellowBox = [ 'Setting a timer' ]
Dieser Code verbirgt nur die Warnung in React Native.

Wie wäre es mit der Warnung in der Browserkonsole?

Weiß jemand, ob jemand aus dem RN-Team oder der Community an einer Lösung für dieses Problem arbeitet?

Das Warn-Popup leitet zu diesem Problem weiter, aber ich kann hier keine andere Lösung finden, als die Warnung auszublenden, was überhaupt keine Lösung ist. Irgendwelche Ideen oder Vorschläge?

@SuhairZain Alles scheint darauf hinzudeuten, dass es sich bei RN um Fehler externer Bibliotheken handelt

@rigobcastro Diese Warnung kann leicht mit einem setInterval() -Anruf mit einer ausreichend langen Zeit (in meinem Fall 5 Minuten) reproduziert werden. Ich würde also sagen, dass dies nicht durch Bibliotheken von Drittanbietern verursacht wird.

Übrigens habe ich seitdem hier eine Bibliothek gefunden: React-Native-Background-Timer, der mir hilft, die Arbeit zu erledigen.

@SuhairZain ja du setInterval() geändert) und die Warnung ist verschwunden.

Gute Empfehlung, danke.

Ich habe das gleiche Problem hier. Und konnte immer noch nicht verstehen, wie ich mit diesem Problem umgehen soll.

rn: 0,45,1
Feuerbasis: 4.1.3

Lieber @escalepion, ich

@escalepion Wenn es bei Ihrem Problem darum geht, Timer mit langer Laufzeit prüfen Sie, ob er Ihnen hilft.

@SuhairZain Entschuldigung, ich konnte nicht verstehen, wie SetInterval oder React-Native-Background-Timer verwendet werden können :( Wo und wie schreibe ich den Code? Hast du ein Beispiel?

Hat jemand einen Tipp, wie man herausfindet, welche Bibliothek den Schaden verursacht? Ich habe kürzlich RN auf 0,46 aktualisiert und plötzlich trat dieser Fehler auf. Ich habe einige Bibliotheken in meinem Projekt und kann mir nur vorstellen, sie einzeln zu untersuchen, was offensichtlich nicht ideal ist.

Prost!

@ abeltje1 , wenn Sie herausfinden, wie dieses Problem

@liketurbo sicher werde ich

Ich habe dieses Problem zusammen mit redux-saga um das API-Token alle 30 Minuten erneut zu validieren.

Daher ist es in diesem Fall tatsächlich richtig, so lange zu warten. Und ich denke, dass es andere Szenarien gibt, in denen lange Wartezeiten erwartet werden.

Dann ist meine Frage, warum ist das eine Warnung? Was kann brechen / passieren? Soll ich keine LLT (langlebige Transaktionen) verwenden können?

Wenn LLT in Ordnung sind. Was wäre der beste Ansatz, um dieses Problem zu lösen? AlarmManager-Zeit verlängern?

Danke im Voraus ;)

Ich habe das gleiche Problem wie @sospedra. Ich verwende redux-saga und habe eine Saga, die alle 3 Minuten einige Daten in der App im Hintergrund aktualisiert, sodass die Saga den Code yield call(delay, 3 * 60000); . Als Ergebnis erhalte ich den Fehler "Einstellen eines Timers für einen langen Zeitraum ...".

Ich frage mich auch, was der vorgeschlagene Ansatz für so etwas ist. Auf welche Probleme stoße ich, wenn ich meinen Code einfach so arbeiten lasse. Die Fehlermeldung impliziert, dass es Leistungsprobleme geben könnte und dass der Timer möglicherweise nicht zum richtigen Zeitpunkt ausgelöst wird, wenn sich die App im Hintergrund befindet.

Wenn es wahrscheinlich Probleme mit diesem Code gibt, der einen 3-Minuten-Timer einstellt, welche alternative Lösung würde dieselbe Funktionalität erreichen und nicht auf diese Probleme stoßen?

immer noch das gleiche Problem.

Ich denke, die einzige Lösung ist die Umstellung auf native Android-Entwicklung

Das Problem kann immer noch nicht gelöst werden? Hat jemand die Lösung gefunden?

Ich werde gewarnt, wenn ich Firebase benutze.

Wenn das Problem nicht aus einer Bibliothek eines Drittanbieters stammt, sondern Sie selbst eine lange Zeitüberschreitung festlegen, ist es eine gute Lösung, die Bibliothek " React-Native-Background-Timer" zu verwenden. Die README-Datei enthält auch ein einfaches Beispiel.

Leider, wenn die Ausgabe aus einer 3rd - Party - Bibliothek ist, haben Sie wahrscheinlich keine andere Lösung als den Ort zu finden , anstatt die oben genannte Bibliothek zu verwenden, benutzen Sie bitte meine mögliche Lösung versucht unten an https://github.com/facebook/react-native/issues/12981#issuecomment -331074444 und versuchen Sie, ob es für Sie funktioniert.

Bitte machen Sie auch auf Android eine tolle Auszeit.

React -Native-Background-Timer ist eine gute Problemumgehung , wie

Ich erhalte diese Warnung, wenn ich socket.io verwende

weil socket.io einen timer von 85ms hat

FWIW das passiert mir nur, wenn ich Reactotron während der Entwicklung benutze ...

Hat mich eine Weile verrückt gemacht, muss ich zugeben, aber ich wusste, dass ich die Nachricht nicht ignorieren konnte

Ich arbeite nicht mehr an dem Projekt, mit dem ich dieses Problem hatte, daher kann ich nicht wirklich testen, ob dieser Ansatz funktioniert, sollte es aber zumindest theoretisch. Wenn der Fehler von einem Drittanbieter-Modul stammt, das setTimeout oder setInterval mit einer langen Verzögerung verwendet, sollte dies Ihr Problem beheben können. Was es tut, ist Affen-Patch das globale setTimeout und setInterval, um stattdessen React -Native-Background-Timer zu verwenden:

import BackgroundTimer from 'react-native-background-timer';

setTimeout = BackgroundTimer.setTimeout;
setInterval = BackgroundTimer.setInterval;
clearTimeout = BackgroundTimer.clearTimeout;
clearInterval = BackgroundTimer.clearInterval;

Schreiben Sie diesen Code irgendwo in Ihrer frühen Initialisierung, vorzugsweise index.android.js oder index.ios.js, so früh wie möglich. Wenn jemand dies testen kann, wäre es sehr dankbar.

@SuhairZain : Ihr Vorschlag funktioniert bisher für mich, mit ein paar Verbesserungen:

setTimeout = BackgroundTimer.setTimeout.bind(BackgroundTimer)
setInterval = BackgroundTimer.setInterval.bind(BackgroundTimer)
clearTimeout = BackgroundTimer.clearTimeout.bind(BackgroundTimer)
clearInterval = BackgroundTimer.clearInterval.bind(BackgroundTimer)

@levity Ich habe Ihren Code zu meiner app.js hinzugefügt, aber ich habe diesen bekommen

undefined ist kein Objekt (Auswertung von 'RNBackgroundTimer.setTimeout')

@realtebo klingt so, als hätten Sie die Installation des Datei beschrieben , möglicherweise nicht abgeschlossen, indem Sie entweder react-native link oder CocoaPods verwendet haben.

@levity : react-native link laufen lassen?

npm install -g react-native-cli
reaktionsnativer Link
Durchsuchen von Ordnern nach Symlinks in C: \ Users \ realtebo \ Downloads \ manager2 \ node_modules (54 ms)
react-native link kann nicht in Create React Native App-Projekten verwendet werden. Wenn Sie eine Bibliothek einfügen müssen, die auf benutzerdefiniertem nativem Code basiert, müssen Sie möglicherweise zuerst auswerfen. Weitere Informationen finden Sie unter https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md .

Ich möchte nicht auswerfen ... also ... was kann ich tun?

Oh, sorry, ich weiß nicht, wie ich Ihnen bei einem Create React Native App-Projekt helfen kann. Ich habe das selbst nie benutzt.

Hallo,
Ich habe einige Probleme mit react-native: ^0.49.3 ...

vgl. https://github.com/ocetnik/react-native-background-timer/issues/65

Hoffe du kannst helfen, danke für deine Zeit;)

Hallo, ich habe das gleiche Problem, das ich mit 0.49 . Es ist danach aufgetreten

export function saveUserData(userInfo){
  return (dispatch) => {
    dispatch(saveDataRequest())
    const userId = firebase.auth().currentUser.uid;
    return firebase.database().ref('users/' + userId).set(userInfo)
      .then(() => {
        dispatch(saveDataSuccess());
        dispatch(NavigationActions.navigate({ routeName: 'TabContactNavigation' }))
      })
      .catch((error) => {
        dispatch(saveDataFailure(error))
      });
  }
}

Das obige ist Action in Redux, das auch redux-thunk . Wenn Sie auf eine Schaltfläche klicken, um Daten aus einem Formular in firebase speichern, wird beim erfolgreichen Speichern saveDataSuccess() und navigieren Sie dann zur nächsten Registerkarte.
Jetzt vermute ich, dass das Problem hier zu sein scheint const userId = firebase.auth().currentUser.uid aber ich bin mir nicht sicher. Hier ist ein Screenshot des Problems. (Die App funktioniert einwandfrei, aber diese Warnung wird angezeigt. Ich weiß nicht, ob ich sie einfach ignorieren soll.) Oder vielleicht mache ich hier etwas falsch. Brauche deine Hilfe, danke

warning

warning2

Hey, die Warnung bezieht sich auf setTimeout. Verwenden Sie es in Ihrer Komponente?
und ja, die Zeile const userId = firebase.auth (). currentUser.uid; funktioniert nicht, das ist ein Versprechen und wenn Sie userId verwenden, kommt es immer noch nicht.
Eine bessere Möglichkeit besteht darin, die Benutzer-ID vom actionCreator abzurufen. Sie senden bereits die Variable userInfo. Versuchen Sie Folgendes:

Ich gehe davon aus, dass die userInfo von der Firebase-Authentifizierung kommt, also haben Sie die UID darin

Exportfunktion saveUserData (userInfo) {
Rückgabe (Versand) => {
Versand (saveDataRequest ())
// const userId = firebase.auth (). currentUser.uid;
return firebase.database (). ref ('users /' + userInfo.uid) .set (userInfo)
.then (() => {
dispatch (saveDataSuccess ());
dispatch (NavigationActions.navigate ({routeName: 'TabContactNavigation'}))
})
.catch ((Fehler) => {
Versand (saveDataFailure (Fehler))
});
}}
}}
Ich hoffe das könnte helfen und entschuldige mein schlechtes Englisch = P.

Glückseligkeit

El 23/10/2017, a las 23:59, Yasir [email protected] escribió:

Hallo, ich habe das gleiche Problem, das ich mit 0,49 verwende. Es ist danach aufgetreten

Exportfunktion saveUserData (userInfo) {
Rückgabe (Versand) => {
Versand (saveDataRequest ())
const userId = firebase.auth (). currentUser.uid;
return firebase.database (). ref ('users /' + userId) .set (userInfo)
.then (() => {
dispatch (saveDataSuccess ());
dispatch (NavigationActions.navigate ({routeName: 'TabContactNavigation'}))
})
.catch ((Fehler) => {
Versand (saveDataFailure (Fehler))
});
}}
}}
Das Obige ist Aktion in Redux, bei der auch Redux-Thunk verwendet wird. Wenn auf eine Schaltfläche geklickt wird, um Daten aus einem Formular in der Firebase zu speichern, wird beim erfolgreichen Speichern saveDataSuccess () ausgelöst und anschließend zur nächsten Registerkarte navigiert.
Jetzt vermute ich, dass das Problem hier zu sein scheint const userId = firebase.auth (). CurrentUser.uid, aber ich bin nicht sicher. Hier ist ein Screenshot des Problems. (Die App funktioniert einwandfrei, aber diese Warnung wird angezeigt. Ich weiß nicht, ob ich sie einfach ignorieren soll.) Oder vielleicht mache ich hier etwas falsch. Brauche deine Hilfe, danke

https://user-images.githubusercontent.com/12644122/31925375-94b7c464-b89d-11e7-889d-e9d00866ff73.png
https://user-images.githubusercontent.com/12644122/31925386-9e9bf3c4-b89d-11e7-9eaa-65147879629f.png
- -
Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub https://github.com/facebook/react-native/issues/12981#issuecomment-338874018 an oder schalten Sie den Thread https://github.com/notifications/unsubscribe-auth/ stumm.

Normalerweise speichere ich die Benutzerinfo in einem Redux-Speicher.
Also verwende ich es einfach nach Bedarf wieder.
... aber ... in einer ähnlichen Situation habe ich das gleiche identische Problem mit dem Timeout

Gleiches Problem mit der React-Native-Signalr-Bibliothek (300000 ms)

socket.io Serveroptionen
pingTimeout (60000) + pingInterval (25000) <= 60000

Gibt es ein Update, wie wir auf Android damit umgehen sollen? Ich bekomme es immer noch und benutze setTimeout auch nicht ...

Nur um meinem vorherigen Kommentar (vom August) zu folgen, der meiner Ansatz für die Abwicklung langlebiger Transaktionen zu kennen

cc @shergin @cpojer @javache @hramos

Ein Fix für React-Native-Signalr (ms-Signalr-Client) unter Android besteht darin, das Standard-Ping-Intervall (300000) zu überschreiben:
connection.start({ pingInterval: 5000, jsonp: true, transport: ['webSockets', 'serverSentEvents', 'longPolling']}).done(() => { console.log('Now connected, connection ID =' + connection.id) })

Gleiches Problem mit reaktionsnativen Pampelmusen (80000ms)

console.ignoredYellowBox = ['Setting a timer'];

Dies ist als Problemumgehung ziemlich sicher, da Sie beim Remote-Debuggen weiterhin die Warnung in der Chrome-Konsole erhalten

Wo genau ist der beste Ort, um den Code zum Ignorieren der Konsole zu platzieren? '

- egal, habe einen Hinweis vom verknüpften Stapelaustausch erhalten , der wie folgt zu meiner App.js hinzugefügt wurde:

class App extends Component {
  constructor() {
    super();

    console.ignoredYellowBox = [
      'Setting a timer'
    ];
  }
...
}
````

and also tried in my index.js as <strong i="8">@haikyuu</strong> just recommended..

{AppRegistry} aus 'react-native' importieren;
App aus './App' importieren;

console.ignoredYellowBox = [
'Timer einstellen'
];

AppRegistry.registerComponent ('manager', () => App);
`` ``

arbeitete in beiden

@CopyJosh können Sie es in Ihre index.js

Es gibt also noch keine Lösung dafür? Es ist jetzt 8+ Monate her ..

?

Lassen Sie uns das dann lösen. Wir müssten wahrscheinlich herausfinden:

A.) Eine einfach erweiterbare API, die über den React-Code aufgerufen werden kann. Ich denke, es wäre klug, vielleicht nur eine der AlarmManager-Methoden zum Laufen zu bringen. Wenn Sie beispielsweise die folgende Methode in Ihrem React Native-Code aufrufen, wird mit dem nativen AlarmManager für Android-Geräte ein Alarm ausgelöst.
AlarmMgr.setInexactRepeating(arg1, arg2...)

B.) Die tatsächliche Umsetzung, um dies zum Laufen zu bringen. Soweit ich weiß, sendet das Einstellen eines Alarms mit AlarmManager eine sogenannte "ausstehende Absicht" an den AlarmManager-Dienst. Sie teilen AlarmManager mit, dass Sie in Zukunft eine Art "Aufgabe" ausführen möchten. Es scheint mir, dass Sie AlarmManager (oder eine benutzerdefinierte React Java-Methode) benötigen würden, um eine Art von Daten an Ihren JavaScript-Code zurückzusenden und ihm mitzuteilen, welcher Code ausgeführt werden soll, nachdem der Alarm ausgelöst wurde.

Ist jemand bereit, dieses Problem anzugehen? Weitere Informationen finden Sie im AlarmManager hier .

Übrigens - ist diese Ineffizienz (im Zusammenhang mit langen Zeitüberschreitungen von mehreren Minuten) nur für RN-Versionen> 0,43 ein neues Problem? Oder wird die Warnung nur von RN> 0,43 ausgespuckt? Ich bin von 0.43.x auf 0.47.x migriert und habe die Warnung gesehen. Ich nahm an, dass die Ineffizienz immer da war und dass RN mich gerade davor gewarnt hat.

Seit der Migration vor einigen Tagen habe ich jedoch auch festgestellt, dass meine App viel mehr Batterie auf meinem Handy verbraucht! (und die anderen Merkmale im Diff sind keine offensichtlichen Schuldigen)

Hey @astreet , gepostet und diese Warnung hier hinzugefügt hast? Https://github.com/facebook/react-native/commit/3637bce479 ?

Es ist mir in letzter Zeit ziemlich ärgerlich geworden, nachdem ich angefangen habe, eine Bibliothek zu verwenden, die einen 2-minütigen wiederkehrenden Timer einstellt.

Jetzt mache ich mir Sorgen um diesen Satz: "Hält das Timing-Modul wach". Ich denke, Sie beziehen sich möglicherweise darauf, dass das Timer-Modul den Choreographen-Rückruf einstellt. Obwohl der Rückruf eingestellt zu sein scheint, unabhängig davon, ob wir den Timer haben oder nicht. Siehe entsprechenden Codeteil hier: https://github.com/facebook/react-native/blob/1e8f3b11027fe0a7514b4fc97d0798d3c64bc895/ReactAndroid/src/main/java/com/facebook/react/modules/core/Timing.java#
Es gibt keinen Code zum Stoppen des Rückrufs, wenn keine Timer geplant sind, und keinen Code zum Starten der Planung, wenn der Timer hinzugefügt wird. Der Rückruf wird nur angehalten, wenn die App in den Hintergrund verschoben und wiederhergestellt wird, wenn sie wieder in den Vordergrund verschoben wird.

Infolgedessen wird der Choreograf-Rückruf für jedes Frame in die Warteschlange gestellt, unabhängig davon, ob ein Timer für einen langen Zeitraum, einen kurzen Zeitraum oder überhaupt kein Timer eingestellt ist. Ich sehe nicht, wie sich das Einstellen eines langen Timers in diesem Fall auf die Leistung auswirken kann. Bedeutet das also, dass die Warnung nicht notwendig ist?

Was das Einstellen eines langen Timers als "Korrektheitsproblem" betrifft, so beziehen Sie sich meiner Meinung nach auf die Tatsache, dass Timer nur im Vordergrund-App-Status aufgerufen werden (wenn Sie ihn also für eine längere Zeit in der Zukunft einstellen und die App in bg wechselt Entweder wird es nicht ausgeführt oder es wird ausgeführt, wenn die App in den Vordergrund tritt, was erheblich später sein kann, als Sie erwarten würden. Obwohl ich glaube, dass dies der gleiche Fall für iOS ist, bei dem die Warnung nicht angezeigt wird

In socket.io ist die Standard-Ping-Schleife 85000 ms, = pingInterval (25000 ms) + pingTimeout (60000 ms). und Sie sollten diese Optionen im Server zurücksetzen und sicherstellen, dass die Summe von pingInterval und pingTimeout <= 60000ms.

zum Beispiel:

var socket = require('socket.io')(12345, {
  pingInterval: 20000, 
  pingTimeout: 40000
})

Nur neugierig - ich muss in meiner App eine Zeitüberschreitung von ca. 5 Minuten einstellen können. Wie ernst ist dieses Problem und wie sehr würde es mich betreffen?

@ntomallen Wenn die App die ganze Zeit auf dem Bildschirm angezeigt wird, ändert sich nichts. Es wird reibungslos funktionieren. Andernfalls wird es möglicherweise am Ende der 5 Minuten nicht ausgelöst. Oder es wird ungenau tun.

Ich verwende Laravel Echo mit React Native auf Android Change Socket Server Optionen pingTimeout bis 30000. Es funktioniert

@sospedra gotcha. Ich muss einige Tests durchführen, um sicherzustellen, dass es nicht so schlimm ist!

Gibt es einen Grund, Handler.postDelayed nicht immer zu verwenden?

Gibt es eine schnelle Lösung für dieses Problem? Ich habe gerade angefangen, RN mit Firebase zu verwenden.

Ich habe ein paar verschiedene Timer-Lösungen ausprobiert, hatte aber kein Glück, eine (konsequent) im Hintergrund zum Laufen zu bringen.

Ich habe ein setInterval verwendet, um meinen Server alle 10 Minuten zu pingen. Ich habe diese Fehlermeldung gerade bemerkt, weil ich ein setInterval(myFunction, 60000) mache. Muss ich mir darüber Sorgen machen?

Mein erwartetes Verhalten ist, dass die App, während sie geöffnet ist, die Anforderungen senden kann, aber nachdem die App angehalten wurde (einmaliges Drücken der Home-Taste), sollten die Anforderungen nicht mehr ausgelöst werden. Ist dies das Verhalten, das ich erwarten kann, und wird die Akkulaufzeit beeinträchtigt, während die App angehalten wird?

Hier gibt es keinen Grund zur Sorge, und die Warnung ist falsch und sollte entfernt werden. Es gibt kein "Timing-Modul", um wach zu bleiben, es gibt nur einen Choreographer-Rückruf, der in jedem Frame nach Timern sucht (wodurch die minimale Granularität für Timer ~ 16 ms beträgt).

Es gibt ein Korrektheitsproblem in dem Sinne, dass Timer unter iOS oder Android nicht im Hintergrund ausgelöst werden. Diese Warnung scheint sich jedoch speziell auf Android zu beziehen und scheint nicht korrekt zu sein. Alle Timer sollten irgendwann ausgelöst werden, wenn die App wieder in den Vordergrund tritt.

Gibt es Pläne, dies bald zu beheben? Das Protokoll ist immer dann ärgerlich, wenn wir auf Android-Handys testen.

Mein Problem…

Ich habe diesen Fehler erhalten, weil meine Zeitüberschreitung bis zu ~ 59 Minuten betrug. Der Code zum Aufrufen einer Methode zu Beginn der Stunde und mit einem setTimeout zum Erstellen eines setInterval am nächsten Ende der Stunde.

Meine Lösung…

  1. Aktualisieren Sie die setTimeout , um die setInterval am Anfang der Minute zu starten.
  2. Aktualisieren Sie die vom setInterval aufgerufene Funktion, um die Funktion nur auszuführen, wenn die aktuellen Minuten 0 .

Diese Funktion läuft jetzt jede Minute statt jede Stunde… aber da sie 59 Mal von 60 nichts tut, scheint sie harmlos zu sein.

hey @beausmith , ist das wirklich eine Lösung, um einfach 60 Timer einzustellen? Nach meinem Verständnis bleibt das timerModule immer noch für dieselbe Stunde aktiv, zeigt aber keine Warnung an :)

@newah - ja, es ist ein bisschen hacky ... kannst du eine bessere Lösung vorschlagen?

@beausmith , ich habe versucht, https://github.com/ocetnik/react-native-background-timer zu verwenden, das native Timer verwendet, was wie eine Lösung klingt. Ich habe setTimout und setInterval einfach mit der Implementierung dieser Bibliothek überschrieben.

Die Unterstützung von Timern im Hintergrund kann je nach Bedarf ein Plus oder Minus sein :))

Scheint gut zu funktionieren, hat aber meine Probleme nicht gelöst :)

Ich habe die gleiche Warnung, wenn ich react-intl FormattedRelative verwende. Da innerhalb der Komponente FormattedRelative Timer verwendet wird:

scheduleNextUpdate(props, state) {
    // Cancel and pending update because we're scheduling a new update.
    clearTimeout(this._timer);

    const {value, units, updateInterval} = props;
    const time = new Date(value).getTime();

    // If the `updateInterval` is falsy, including `0` or we don't have a
    // valid date, then auto updates have been turned off, so we bail and
    // skip scheduling an update.
    if (!updateInterval || !isFinite(time)) {
      return;
    }

    const delta = time - state.now;
    const unitDelay = getUnitDelay(units || selectUnits(delta));
    const unitRemainder = Math.abs(delta % unitDelay);

    // We want the largest possible timer delay which will still display
    // accurate information while reducing unnecessary re-renders. The delay
    // should be until the next "interesting" moment, like a tick from
    // "1 minute ago" to "2 minutes ago" when the delta is 120,000ms.
    const delay =
      delta < 0
        ? Math.max(updateInterval, unitDelay - unitRemainder)
        : Math.max(updateInterval, unitRemainder);

    this._timer = setTimeout(() => {
      this.setState({now: this.context.intl.now()});
    }, delay);
  }

Hier ist ein Beispiel für die Verwendung in meinem Code:

<FormattedRelative value={date}>
    {(message: string) => <Text>{message}</Text>}
</FormattedRelative>

Weiß jemand, wie man diese Warnung behebt?

Dies ist immer noch ein Problem. Es ist besonders ärgerlich, wenn Firebase-Dienste auf Android verwendet werden. Bitte repariere.

Dies ist ein wirklich schlimmer Fehler für Firebase-Dienste und wenn Sie auf Apps von Drittanbietern angewiesen sind. Weil Firebase nicht funktioniert, wenn Sie zwischen Apps wechseln, um etwas zu überprüfen, um den Vorgang fortzusetzen.

Ein Beispiel ist, dass wir ein Drittanbieter- / Faktor-Anmeldesystem verwenden und Firebase verwenden, um Token zu verschieben. Aber da wir aufräumen, ist der Token weg, bevor die Person wieder in unserer App ist. Also kann ich die Aufräummechanismen ändern, oder ihr könnt diesen Fehler beheben.

@vongohren nicht, dass ich Ihren Anwendungsfall vollständig verstehe, aber eine Problemumgehungsstrategie könnte darin bestehen, das Hintergrunddatum in Ihrer App beim Eintritt in den Hintergrund zu speichern und dann bei der Rückkehr in den Vordergrund das aktuelle Datum mit dem gespeicherten Hintergrunddatum zu vergleichen und eine Bereinigung durchzuführen wenn ein bestimmter Zeitraum verstrichen ist ...

Um auf meinen Anwendungsfall einzugehen. Angenommen, Sie müssen in einer anderen App Ja sagen, um die Anmeldung zu akzeptieren. Feks wechselt zur Facebook-App, um eine Anmeldeanforderung eines Dritten zu bestätigen. Das konkrete Beispiel, mit dem ich arbeite, ist uPort, https://www.uport.me/. Wenn wir uns dann auf eine Möglichkeit verlassen, unsere App zu benachrichtigen, jetzt im Hintergrund, um zu sagen, dass alles in Ordnung ist, funktioniert dies nicht mit Firebase, es sei denn, wir gehen von Ihrem Ansatz aus, um zu einem späteren Zeitpunkt aufzuräumen.

Ich glaube, ich war nur fest davon überzeugt, dass die Bereinigung direkt nach der Ausgabe der Informationen erfolgen könnte, da die Informationen dann bereits gesendet wurden und wir sie nicht benötigen würden. Aber warum ist es so, dass der Firebase-Ansatz nicht in React Native funktioniert? Dass es seine Hintergrundarbeiter aufhält.

Ich benötige eine 30-minütige Zeitüberschreitung in meiner App. Jedes Mal, wenn der Benutzer mit dem Bildschirm interagiert, wird er zurückgesetzt (alte Zeitüberschreitung wegwerfen, neue erstellen).

Gibt es eine Alternative, wie man das richtig macht? Ist es besser, dies mit nativem Code zu handhaben und etwas an React zu übergeben, wenn Sie fertig sind?

wow, also das ist immer noch ein Problem

@nbennink Antwort hier überprüfen. Derzeit gibt es keine Garantie für die Ausführung von Aufgaben im Hintergrund, da mehrere Faktoren im Spiel sind (Batteriesparmodus, Benutzerinteraktion usw.).

Ich bekomme auch die gleiche Warnung, nachdem ich socket.io benutzt habe.
Warnung ist unten:

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info.
(Saw setTimeout with duration 85000ms)

Meine Paketdetails sind unten:

  • "reagieren": "^ 16.3.0-alpha.1",
  • "reaktionsnativ": "0,54,4",
  • "socket.io": "^ 2.1.1",
  • "socket.io-client": "^ 2.1.1",

Irgendeine dauerhafte Lösung herausfinden?

Ich bekomme auch die gleiche Warnung, nachdem ich socket.io benutzt habe.
Warnung ist unten:

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info.
(Saw setTimeout with duration 85000ms)

Meine Paketdetails sind unten:

"reagieren": "^ 16.3.0-alpha.1",
"reaktionsnativ": "0,54,4",
"socket.io": "^ 2.1.1",
"socket.io-client": "^ 2.1.1",

Irgendeine dauerhafte Lösung herausfinden?

Ditto, gibt es keinen Weg, dies zu umgehen?

Wird dieses Problem immer noch offen sein, wenn diese Warnung immer noch auf reag-native 0.57 angezeigt wird?

Fast ein Jahr und React Native haben immer noch das gleiche Problem !!!

Bei demselben Problem wird dieselbe Warnung 3-4 Mal angezeigt. Sehr nervig.

Gibt es eine Lösung, um dieses Problem zu lösen?

Die Warnmeldung wurde durch diese Lösung https://stackoverflow.com/a/48778011/7427111 entfernt

Es ist im Grunde nur das Verstecken der Nachricht, ohne das Problem zu beheben, denke ich.

@dhavaljardosh Ja, deine Vermutung ist richtig.

Ich habe einen nativen Timer mit Java und Objective C erstellt. Er funktioniert für mich und verbirgt die Nachricht. Ich bin mir nicht sicher, ob es tatsächlich die Leistung verbessert. Wie oben erwähnt: Es ist immer noch schlecht für die Batterie usw., weil im Hintergrund ein langer Timer ist.

Eine Frage ist, ob Sie wirklich eine Abfragefunktion benötigen. Ich dachte, ich hätte es getan, aber dann wurde mir aufgrund dieses Problems klar, dass ich nur in einem halbwegs häufigen Zeitraum ausführen musste. Jetzt führe ich es im App-Hintergrund aus und vermeide dieses Problem vollständig. YMMV.

gleiches Problem bei der Verwendung von Pusher ...

Ich werde meine App testen, um festzustellen, welche Auswirkungen die Leistung hat, wenn alle 60 Sekunden ein Timer eingestellt wird.
Ich gehe jedoch davon aus, dass einige von Ihnen Erfahrung damit haben. Können Sie diese Erfahrung bitte teilen? Ist die Auswirkung erheblich?

immer noch das gleiche Problem mit der neuesten Version.
irgendeine Lösung?

Ich stehe auch vor diesem Problem.
Die App funktionierte einwandfrei. Erst als ich anfing, Firebase zu verwenden, kam die Warnung.
Irgendeine Lösung?

Ich möchte die Bedeutung dieser Nachricht verstehen, da wir sie nach einer kürzlich zu unserem Produkt hinzugefügten Funktion erhalten haben. Liegt das Problem nur darin, dass der Timer weiter läuft, während die App im Hintergrund ist? Wäre es eine geeignete Lösung, App-Statusereignisse zu abonnieren und den Timer anzuhalten, wenn die App im Hintergrund ausgeführt wird? Oder ist ein lang laufender Timer mit der App auch im Vordergrund problematisch?

Ich möchte die Bedeutung dieser Nachricht verstehen, da wir sie nach einer kürzlich zu unserem Produkt hinzugefügten Funktion erhalten haben. Liegt das Problem nur darin, dass der Timer weiter läuft, während die App im Hintergrund ist? Wäre es eine geeignete Lösung, App-Statusereignisse zu abonnieren und den Timer anzuhalten, wenn die App im Hintergrund ausgeführt wird? Oder ist ein lang laufender Timer mit der App auch im Vordergrund problematisch?

Würde das auch gerne wissen.

Was passiert außerdem mit setInterval? Ich bekomme keine Warnungen von diesem, aber hat es das gleiche Problem?

Ich möchte die Bedeutung dieser Nachricht verstehen, da wir sie nach einer kürzlich zu unserem Produkt hinzugefügten Funktion erhalten haben. Liegt das Problem nur darin, dass der Timer weiter läuft, während die App im Hintergrund ist? Wäre es eine geeignete Lösung, App-Statusereignisse zu abonnieren und den Timer anzuhalten, wenn die App im Hintergrund ausgeführt wird? Oder ist ein lang laufender Timer mit der App auch im Vordergrund problematisch?

In der gelben Nachricht heißt es: "... und Timer können nur aufgerufen werden, wenn sich die App im Vordergrund befindet."
Timer-Modul bleibt wach, aber Timer können nicht funktionieren, wenn sich die App im Hintergrund befindet? Das Problem ist also, das Timer-Modul wach zu halten, wenn eine App im Hintergrund ist? Wie viel Leistung / Batterieeffekt hätte das, frage ich mich ...

@BerndWessels https://www.npmjs.com/package/react-native-firebase Haben Sie sich das angesehen? Sagt, dass Firebase auf dem nativen Thread ausgeführt werden kann. Ich bin mir nicht sicher, wie wahr das ist, könnte aber einen Blick wert sein. Sie könnten das sogar benutzen, ich bin mir nicht sicher.

Denken Sie, wenn ich zu dieser Bibliothek wechsle, muss ich meinen vorhandenen Code ändern? Ich meine, das wäre nicht sehr schön ...

Das gleiche Problem mit Pusher auf dem neuesten RN0.59, und die Benutzeroberfläche kann einige Sekunden hängen bleiben ...

Dieses Problem tritt anscheinend nur auf, wenn ich die Echtzeitdatenbank von firebase aufrufe.

await firebase.database().ref('users/' + id).set(data);

RN 0,57,1

Ich habe nicht mit 0,59 bestätigt.

@swushi Ich 0.59

Ich erhalte folgende Warnung, wenn ich die Firebase-Bibliothek verwende

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and correctness issue on Android as it keeps the timer module awake, and timers can only be called when the app is in the foreground. See https://github.com/facebook/react-native/issues/12981 for more info. (Saw setTimeout with duration 111862ms)

Wie man diese Warnung loswird ...

Weiß jemand, wie man diese Warnung loswird, ohne sie zu verbergen?
Ich benutze die firebase -Bibliothek, nicht die React-Native-Firebase, aber es scheint dasselbe Problem zu geben, und ich weiß nicht, wie sich das auf mich auswirkt, wenn es um die Produktion geht.

Ich mache mir wirklich Sorgen, wenn jemand helfen könnte, bitte ...

Ich verwende den folgenden Code, um dieses Problem (im Moment) zu umgehen:

Siehe https://github.com/firebase/firebase-js-sdk/issues/97#issuecomment -427512040

fixtimerbug.js

/////////////////////////////////////////////////////////////////////////////
////// temporary fix to bug about 'Setting a timer' /////////////////////////
////// See: https://github.com/pusher/pusher-js/issues/248 //////////////////
////// See: https://github.com/facebook/react-native/issues/12981 ///////////
////// See: https://github.com/firebase/firebase-js-sdk/issues/97 ///////////
/////////////////////////////////////////////////////////////////////////////
import { Platform, InteractionManager } from 'react-native';
const _setTimeout = global.setTimeout;
const _clearTimeout = global.clearTimeout;
const MAX_TIMER_DURATION_MS = 60 * 1000;
if (Platform.OS === 'android') {
  const timerFix = {};
  const runTask = (id, fn, ttl, args) => {
    const waitingTime = ttl - Date.now();
    if (waitingTime <= 1) {
      InteractionManager.runAfterInteractions(() => {
        if (!timerFix[id]) {
          return;
        }
        delete timerFix[id];
        fn(...args);
      });
      return;
    }
    const afterTime = Math.min(waitingTime, MAX_TIMER_DURATION_MS);
    timerFix[id] = _setTimeout(() => runTask(id, fn, ttl, args), afterTime);
  };
  global.setTimeout = (fn, time, ...args) => {
    if (MAX_TIMER_DURATION_MS < time) {
      const ttl = Date.now() + time;
      const id = '_lt_' + Object.keys(timerFix).length;
      runTask(id, fn, ttl, args);
      return id;
    }
    return _setTimeout(fn, time, ...args);
  };
  global.clearTimeout = id => {
    if (typeof id === 'string' && id.startsWith('_lt_')) {
      _clearTimeout(timerFix[id]);
      delete timerFix[id];
      return;
    }
    _clearTimeout(id);
  };
}
/////////////////////////////////////////////////////////////////////////////

@cpmech
Sie implementieren dies in einer unabhängigen .js-Datei oder tun dies innerhalb des Skripts, das die Timer-Ausnahme auslöst

Hallo, ja, der obige Code befindet sich in einer Datei mit dem Namen 'fixtimerbug.js'. Dann lade ich es wie folgt in meine App.js:

import './src/fixtimerbug'; // <<<<<<<<<<<<<<<<<<

import React from 'react';
import { Platform, View, StatusBar } from 'react-native';
import AppNavigator from './src/navigation/AppNavigator';
import Store from './src/model/Store';

const store = new Store();

const App = () => (
  <View style={{ flex: 1, backgroundColor: '#fff' }}>
    {Platform.OS === 'ios' && <StatusBar barStyle="default" />}
    <AppNavigator screenProps={{ store }} />
  </View>
);

export default App;

Scheint, dass es gut funktioniert, was macht es genau?

Vielen Dank @cpmech

Hallo, der Code (von hier: https://github.com/firebase/firebase-js-sdk/issues/97#issuecomment-427512040) umschließt einfach die Funktion setTimeout (global), um dies zu verhindern mit einer langen Zeit verwendet.

Wenn in unserer modifizierten global.setTimeout -Funktion die Dauer größer als der Schwellenwert MAX_TIMER_DURATION_MS , speichern wir id in einer lokalen Karte ( timerFix ) und dann Rufen Sie runTask wodurch die Dauer in kleinere Werte aufgeteilt wird. runTask legt eine Zeitüberschreitung (unter Verwendung der ursprünglichen _setTimeout ) mit den kleineren Blöcken fest, die kontinuierlich ausgeführt werden, bis waitingTime zu klein ist. Wenn waitingTime klein genug ist, rufen wir React Native's runAfterInteractions für eine reibungslose Ausführung auf und entfernen gleichzeitig den Eintrag id von unserer lokalen Karte, weil wir gewonnen haben In diesem Fall wird _setTimeout erneut angerufen. Beachten Sie, dass afterTime in _setTimeout eingespeist wird, um zu verhindern, dass es mit einem langen Zeitraum aufgerufen wird.

Andernfalls rufen wir in unserer modifizierten global.setTimeout -Funktion, wenn die Dauer kleiner als der Schwellenwert MAX_TIMER_DURATION_MS , direkt das globale setTimeout auf (gespeichert in _setTimeout ).

Das globale clearTimeout wird ebenfalls verpackt, um einen Bereinigungsprozess durchzuführen, indem die id von der lokalen Karte entfernt werden.

Ich hoffe es hilft!

Vor dem gleichen Problem. Scheint, als müssten wir die Warnung vorerst verbergen. Hier ist der kürzeste Weg, dies zu tun:
componentDidMount() { console.disableYellowBox = true; ... }

Hallo, der Code (von hier: firebase / firebase-js-sdk # 97 (Kommentar) ) setTimeout (global), um zu verhindern, dass sie über einen längeren Zeitraum verwendet wird.

Wenn in unserer modifizierten global.setTimeout -Funktion die Dauer größer als der Schwellenwert MAX_TIMER_DURATION_MS , speichern wir id in einer lokalen Karte ( timerFix ) und dann Rufen Sie runTask wodurch die Dauer in kleinere Werte aufgeteilt wird. runTask legt eine Zeitüberschreitung (unter Verwendung der ursprünglichen _setTimeout ) mit den kleineren Blöcken fest, die kontinuierlich ausgeführt werden, bis waitingTime zu klein ist. Wenn waitingTime klein genug ist, rufen wir React Native's runAfterInteractions für eine reibungslose Ausführung auf und entfernen gleichzeitig den Eintrag id von unserer lokalen Karte, weil wir gewonnen haben In diesem Fall wird _setTimeout erneut angerufen. Beachten Sie, dass afterTime in _setTimeout eingespeist wird, um zu verhindern, dass es mit einem langen Zeitraum aufgerufen wird.

Andernfalls rufen wir in unserer modifizierten global.setTimeout -Funktion, wenn die Dauer kleiner als der Schwellenwert MAX_TIMER_DURATION_MS , direkt das globale setTimeout auf (gespeichert in _setTimeout ).

Das globale clearTimeout wird ebenfalls verpackt, um einen Bereinigungsprozess durchzuführen, indem die id von der lokalen Karte entfernt werden.

Ich hoffe es hilft!

Ich danke dir sehr! Lief wie am Schnürchen.

Hallo, der Code (von hier: firebase / firebase-js-sdk # 97 (Kommentar) ) setTimeout (global), um zu verhindern, dass sie über einen längeren Zeitraum verwendet wird.

Wenn in unserer modifizierten global.setTimeout -Funktion die Dauer größer als der Schwellenwert MAX_TIMER_DURATION_MS , speichern wir id in einer lokalen Karte ( timerFix ) und dann Rufen Sie runTask wodurch die Dauer in kleinere Werte aufgeteilt wird. runTask legt eine Zeitüberschreitung (unter Verwendung der ursprünglichen _setTimeout ) mit den kleineren Blöcken fest, die kontinuierlich ausgeführt werden, bis waitingTime zu klein ist. Wenn waitingTime klein genug ist, rufen wir React Native's runAfterInteractions für eine reibungslose Ausführung auf und entfernen gleichzeitig den Eintrag id von unserer lokalen Karte, weil wir gewonnen haben In diesem Fall wird _setTimeout erneut angerufen. Beachten Sie, dass afterTime in _setTimeout eingespeist wird, um zu verhindern, dass es mit einem langen Zeitraum aufgerufen wird.

Andernfalls rufen wir in unserer modifizierten global.setTimeout -Funktion, wenn die Dauer kleiner als der Schwellenwert MAX_TIMER_DURATION_MS , direkt das globale setTimeout auf (gespeichert in _setTimeout ).

Das globale clearTimeout wird ebenfalls verpackt, um einen Bereinigungsprozess durchzuführen, indem die id von der lokalen Karte entfernt werden.

Ich hoffe es hilft!

Behebt dies tatsächlich das Problem oder wird nur die Warnung entfernt?

Hallo, der Code (von hier: firebase / firebase-js-sdk # 97 (Kommentar) ) setTimeout (global), um zu verhindern, dass sie über einen längeren Zeitraum verwendet wird.

Wenn in unserer modifizierten global.setTimeout -Funktion die Dauer größer als der Schwellenwert MAX_TIMER_DURATION_MS , speichern wir id in einer lokalen Karte ( timerFix ) und dann Rufen Sie runTask wodurch die Dauer in kleinere Werte aufgeteilt wird. runTask legt eine Zeitüberschreitung (unter Verwendung der ursprünglichen _setTimeout ) mit den kleineren Blöcken fest, die kontinuierlich ausgeführt werden, bis waitingTime zu klein ist. Wenn waitingTime klein genug ist, rufen wir React Native's runAfterInteractions für eine reibungslose Ausführung auf und entfernen gleichzeitig den Eintrag id von unserer lokalen Karte, weil wir gewonnen haben In diesem Fall wird _setTimeout erneut angerufen. Beachten Sie, dass afterTime in _setTimeout eingespeist wird, um zu verhindern, dass es mit einem langen Zeitraum aufgerufen wird.

Andernfalls rufen wir in unserer modifizierten global.setTimeout -Funktion, wenn die Dauer kleiner als der Schwellenwert MAX_TIMER_DURATION_MS , direkt das globale setTimeout auf (gespeichert in _setTimeout ).

Das globale clearTimeout wird ebenfalls verpackt, um einen Bereinigungsprozess durchzuführen, indem die id von der lokalen Karte entfernt werden.

Ich hoffe es hilft!

Vielen Dank! Es wird die Gesamtleistung der App nicht beeinflussen, oder?

Hallo, der Code (von hier: firebase / firebase-js-sdk # 97 (Kommentar) ) setTimeout (global), um zu verhindern, dass sie über einen längeren Zeitraum verwendet wird.
Wenn in unserer modifizierten global.setTimeout -Funktion die Dauer größer als der Schwellenwert MAX_TIMER_DURATION_MS , speichern wir id in einer lokalen Karte ( timerFix ) und dann Rufen Sie runTask wodurch die Dauer in kleinere Werte aufgeteilt wird. runTask legt eine Zeitüberschreitung (unter Verwendung der ursprünglichen _setTimeout ) mit den kleineren Blöcken fest, die kontinuierlich ausgeführt werden, bis waitingTime zu klein ist. Wenn waitingTime klein genug ist, rufen wir React Native's runAfterInteractions für eine reibungslose Ausführung auf und entfernen gleichzeitig den Eintrag id von unserer lokalen Karte, weil wir gewonnen haben In diesem Fall wird _setTimeout erneut angerufen. Beachten Sie, dass afterTime in _setTimeout eingespeist wird, um zu verhindern, dass es mit einem langen Zeitraum aufgerufen wird.
Andernfalls rufen wir in unserer modifizierten global.setTimeout -Funktion, wenn die Dauer kleiner als der Schwellenwert MAX_TIMER_DURATION_MS , direkt das globale setTimeout auf (gespeichert in _setTimeout ).
Das globale clearTimeout wird ebenfalls verpackt, um einen Bereinigungsprozess durchzuführen, indem die id von der lokalen Karte entfernt werden.
Ich hoffe es hilft!

Behebt dies tatsächlich das Problem oder wird nur die Warnung entfernt?

Nein, das Problem wird nicht behoben. Es ist nur eine gute Arbeit.

Hallo, der Code (von hier: firebase / firebase-js-sdk # 97 (Kommentar) ) setTimeout (global), um zu verhindern, dass sie über einen längeren Zeitraum verwendet wird.
Wenn in unserer modifizierten global.setTimeout -Funktion die Dauer größer als der Schwellenwert MAX_TIMER_DURATION_MS , speichern wir id in einer lokalen Karte ( timerFix ) und dann Rufen Sie runTask wodurch die Dauer in kleinere Werte aufgeteilt wird. runTask legt eine Zeitüberschreitung (unter Verwendung der ursprünglichen _setTimeout ) mit den kleineren Blöcken fest, die kontinuierlich ausgeführt werden, bis waitingTime zu klein ist. Wenn waitingTime klein genug ist, rufen wir React Native's runAfterInteractions für eine reibungslose Ausführung auf und entfernen gleichzeitig den Eintrag id von unserer lokalen Karte, weil wir gewonnen haben In diesem Fall wird _setTimeout erneut angerufen. Beachten Sie, dass afterTime in _setTimeout eingespeist wird, um zu verhindern, dass es mit einem langen Zeitraum aufgerufen wird.
Andernfalls rufen wir in unserer modifizierten global.setTimeout -Funktion, wenn die Dauer kleiner als der Schwellenwert MAX_TIMER_DURATION_MS , direkt das globale setTimeout auf (gespeichert in _setTimeout ).
Das globale clearTimeout wird ebenfalls verpackt, um einen Bereinigungsprozess durchzuführen, indem die id von der lokalen Karte entfernt werden.
Ich hoffe es hilft!

Vielen Dank! Es wird die Gesamtleistung der App nicht beeinflussen, oder?

Nein, die Leistung wird dadurch überhaupt nicht beeinträchtigt.

Ein kurzer Hinweis zu

Wenn es Sie stört, fügen Sie einfach console.ignoredYellowBox = ['Einstellen eines Timers'] hinzu.

und

Vor dem gleichen Problem. Scheint, als müssten wir die Warnung vorerst verbergen. Hier ist der kürzeste Weg, dies zu tun:
componentDidMount () {console.disableYellowBox = true; ...}

Dies ist keine praktikable Lösung. Die Fehler treten immer noch auf, Sie erhalten einfach keine Benachrichtigung.

Ergebnis? Die Fehleranalyse muss noch durchgeführt werden.

Wenn Sie beispielsweise Firebase-Listener verwenden, verbergen Sie eine große Anzahl von Fehlern, die jedoch von Ihrer Entwicklungsumgebung weiterhin behandelt werden.

Ein typisches Beispiel: Mein expo-basiertes Projekt stürzte immer wieder ab, weil versucht wurde, jeden Timer-Fehler zu erfassen.

Ich schließe dies, weil ich nicht glaube, dass React Native die Unterstützung für AlarmManager im Kern hinzufügen wird. Dies kann mit Modulen von Drittanbietern oder benutzerdefiniertem nativem Code erfolgen.

@cpmechs Lösung funktioniert schon? Ich habe es auf RN60.4 versucht, aber noch eine lange Timer-Warnung erhalten.

Hallo, ich denke ich habe die Lösung gefunden:
Zunächst müssen Sie die folgende Datei in Ihrem Projekt finden: Bibliotheken / Core / Timer / JSTimer; js
Öffnen Sie es und Sie müssen nur diese Konstante ändern. MAX_TIMER_DURATION_MS, um Ihre Dauer zu erhöhen, wurde am Ende der Warnung geschrieben!

Erhöhen Sie den Timer, aber wie viel?

@dulmandakh Gibt es Open-Source-Projekte, die dieses Ihnen bekannte Problem lösen?

@dulmandakh Gibt es Open-Source-Projekte, die dieses Ihnen bekannte Problem lösen?

RNFirebase vielleicht? @ Dulmandakh

Sie können den Timer mit einer festen Zeit neu planen, bis er abläuft:


const setLogoutTimer = expirationTime => {

  return dispatch => {
    timer = setTimeout(() => {
        if (expirationTime>60000)
        {
            console.log(`set new exp:${expirationTime-60000}`);
            dispatch(setLogoutTimer(expirationTime-60000));
        }
        else
        {
            console.log('logout');
            dispatch(logout());
        }
    }, 60000); 
  };
};

Es ist 2 Jahre her, dass native oder Firebase dieses Problem richtig beheben. :(

OK, nach ein paar Stunden langer Untersuchung möchte ich nur wissen, ob ich das Problem irgendwie verursacht habe.
Ich bin mir nicht sicher, wann es erschien.
erscheint es, sobald ich firestore anrufe?
Ich verwende keine Timer in meiner App

@luismasg Ich verwende setTimeout nicht in meinem Code, da dies eine schlechte Praxis ist, aber ich kenne die Fehlerquelle und kann sie nicht stoppen. Es scheint, dass sie vom Herstellen einer Remoteverbindung mit meiner Datenbank stammt, anscheinend von der Bibliothek, die ich verwende Überprüfen Sie Ihre Abhängigkeitsbibliothek, um festzustellen, ob Sie diejenige ermitteln können, die das Problem verursacht

Ehrlich gesagt denke ich nicht, dass die Verwendung von JS-Timern / Intervallen eine gute Idee für Langzeit-Timer ist. Die Warnung gibt es aus einem Grund.

Verwenden Sie stattdessen Lebenszyklusereignisse, um kurze Timer hinzuzufügen / zu entfernen. Wenn Sie eine tatsächliche Hintergrundausführung benötigen, verwenden Sie nativen Code mit Vordergrunddiensten (Android) und Hintergrundaufgaben (iOS).

Ehrlich gesagt denke ich nicht, dass die Verwendung von JS-Timern / Intervallen eine gute Idee für Langzeit-Timer ist. Die Warnung gibt es aus einem Grund.

Wie oben ausführlich erwähnt, haben viele Menschen Probleme mit Bibliotheken, die längere Timer verwenden. "Nur keine Firebase verwenden" ist keine Lösung.

Offensichtlich ist dies ein häufig auftretendes Problem, dessen Behandlung die Entwicklererfahrung von react-native verbessern würde, was sich wie das ultimative Ziel anhört ...

Ich würde nicht sagen, dass "Firebase nicht verwenden" die Antwort ist, eher wie "Firebase so reparieren, dass keine langen Timer verwendet werden und die entsprechenden nativen Bausteine ​​für die Aufgabe verwendet werden, für die sie lange Timer verwenden".

Aber Sie haben Recht, es wäre ideal für RN, Langzeit-Timer irgendwie zu unterstützen, aber angesichts all der Vorbehalte (wie höherer Batterieverbrauch, unnötige Hintergrundausführungszeit usw.) wird es Entwickler nur dazu bringen, sich selbst auf den Fuß zu schießen. Wenn überhaupt, sollte es sich um ein separates Timer- / Intervallprimitiv handeln.

Wenn überhaupt, sollte es sich um ein separates Timer- / Intervallprimitiv handeln.

Mein Verständnis dessen, worum es in diesem Thema geht, ist das Fehlen eines solchen Grundelements 😄

Verwenden Sie den Timer im Timer, das ist alles!

@ Dulmandakh Warum ist dieses Problem geschlossen? Das Problem bleibt bestehen und die Diskussion dauert an?

Ich habe dies zu App.js hinzugefügt und dadurch behoben (vorübergehend, bis es einen offiziellen Fix gibt).

const _setTimeout = global.setTimeout;
const _clearTimeout = global.clearTimeout;
const MAX_TIMER_DURATION_MS = 60 * 1000;
if (Platform.OS === "android") {
  // Work around issue `Setting a timer for long time`
  // see: https://github.com/firebase/firebase-js-sdk/issues/97
  const timerFix = {};
  const runTask = (id, fn, ttl, args) => {
    const waitingTime = ttl - Date.now();
    if (waitingTime <= 1) {
      InteractionManager.runAfterInteractions(() => {
        if (!timerFix[id]) {
          return;
        }
        delete timerFix[id];
        fn(...args);
      });
      return;
    }

    const afterTime = Math.min(waitingTime, MAX_TIMER_DURATION_MS);
    timerFix[id] = _setTimeout(() => runTask(id, fn, ttl, args), afterTime);
  };

  global.setTimeout = (fn, time, ...args) => {
    if (MAX_TIMER_DURATION_MS < time) {
      const ttl = Date.now() + time;
      const id = "_lt_" + Object.keys(timerFix).length;
      runTask(id, fn, ttl, args);
      return id;
    }
    return _setTimeout(fn, time, ...args);
  };

  global.clearTimeout = id => {
    if (typeof id === "string" && id.startWith("_lt_")) {
      _clearTimeout(timerFix[id]);
      delete timerFix[id];
      return;
    }
    _clearTimeout(id);
  };
}

Dies ist eine Problemumgehung, keine Lösung.

Ich habe dies zu App.js hinzugefügt und dadurch behoben (vorübergehend, bis es einen offiziellen Fix gibt).

...
    if (typeof id === "string" && id.startWith("_lt_")) {
...

'startWith' sollte 'startWith' sein, wenn Sie diesen Code verwenden möchten.

Ich erlebe dies mit AWS Amplify Datastore. Anstelle einer ordnungsgemäßen Korrektur deaktiviere ich die Warnung mit

import { YellowBox } from 'react-native';
YellowBox.ignoreWarnings(['Setting a timer']);

Mir ist nicht klar, ob das zugrunde liegende Problem behoben werden muss, Amplify behoben werden muss oder ob ich es reparieren muss. Natürlich möchte ich keine Leistungsprobleme.

Wenn es Sie stört, fügen Sie einfach console.ignoredYellowBox = ['Setting a timer'];

Wo soll ich das hinzufügen? Ich habe versucht, in Bildschirmdatei und Aktionsdatei, immer noch nicht funktioniert

Fügen Sie es einfach irgendwo in Ihre App.js-Datei ein. Ich habe es zum Beispiel in meinen Konstruktor eingefügt.
Ich weiß nicht, ob das der beste Ort ist. Wenn also jemand etwas besseres weiß, würde ich es gerne hören!

Ich denke, wer auch immer Firebase verwendet, kann dieses Problem lösen, indem er die Persistenz der App nach (signIn / signUp) konfiguriert.

* Nachdem Sie einen neuen Benutzer erstellt haben, wird er automatisch angemeldet

https://firebase.google.com/docs/auth/web/auth-state-persistence

Also ... nach der Authentifizierung eines Benutzers wird eine Zeitvariable erstellt.

Die Standardeinstellung für Firebase ist local . "firebase.auth.Auth.Persistence.LOCAL"

Sie können ändern mit:
firebase.auth.Auth.Persistence.SESSION
firebase.auth.Auth.Persistence.NONE

oder mit einem localStorage ...

Bis sie es endgültig lösen ...

{YellowBox} aus "react-native" importieren;
importiere _ aus "lodash";
YellowBox.ignoreWarnings (["Einstellen eines Timers"]);
const _console = _.clone (Konsole);
console.warn = (message) => {
if (message.indexOf ("Timer einstellen") <= -1) {
_console.warn (Nachricht);
}}
};

Einmal gelöst, wird der Junk-Code entfernt und voila!

Dies kann mit RxJS gelöst werden.

Grundsätzlich wird Ihr 5200 Timer in 5 * 1000 + 200 Timer aufgeteilt.

import { of, range } from 'rxjs';
import {
  concatMap,
  delay,
  filter,
  mapTo,
  switchMap,
  tap,
} from 'rxjs/operators';

// ~ setTimeout(..., 5200);

const source = of(5200).pipe(
  switchMap(duration => {
    const times = Math.floor(duration / 1000); // = 5
    const remainder = duration % 1000; // = 200

    return range(1, times).pipe(
      concatMap(i => of(i).pipe(delay(1000))),
      tap(console.log),
      filter(i => i === times),
      delay(remainder),
      tap(console.log),
      mapTo('Done !'),
    );
  }),
);

source.subscribe(console.log);

1 // After 1s
2 // After 2s
3 // After 3s
4 // After 4s
5 // After 5s
5 // After 5s + 200 ms
'Done !'

Ich denke, wer auch immer Firebase verwendet, kann dieses Problem lösen, indem er die Persistenz der App nach (signIn / signUp) konfiguriert.

* Nachdem Sie einen neuen Benutzer erstellt haben, wird er automatisch angemeldet

https://firebase.google.com/docs/auth/web/auth-state-persistence

Also ... nach der Authentifizierung eines Benutzers wird eine Zeitvariable erstellt.

Die Standardeinstellung für Firebase ist local . "firebase.auth.Auth.Persistence.LOCAL"

Sie können ändern mit:
firebase.auth.Auth.Persistence.SESSION
firebase.auth.Auth.Persistence.NONE

oder mit einem localStorage ...

Großartig! Wie wäre es mit Firestore?

Ich denke, wer auch immer Firebase verwendet, kann dieses Problem lösen, indem er die Persistenz der App nach (signIn / signUp) konfiguriert.
* Nachdem Sie einen neuen Benutzer erstellt haben, wird er automatisch angemeldet
https://firebase.google.com/docs/auth/web/auth-state-persistence
Also ... nach der Authentifizierung eines Benutzers wird eine Zeitvariable erstellt.
Die Standardeinstellung für Firebase ist local . "firebase.auth.Auth.Persistence.LOCAL"
Sie können ändern mit:
firebase.auth.Auth.Persistence.SESSION
firebase.auth.Auth.Persistence.NONE
oder mit einem localStorage ...

Großartig! Wie wäre es mit Firestore?

Wenn Sie das alte Firebase-SDK verwenden, migrieren Sie zum Firestore-Administrator-SDK.

Die meisten Probleme werden gelöst

https://firebase.google.com/docs/reference/admin

Noch immer kann niemand dieses Problem lösen. # Schande über Ihre Entwickler; p

Noch immer kann niemand dieses Problem lösen. # Schande über Ihre Entwickler; p

Schäme niemals Open Source-Mitwirkende. Es ist eine Schande, dass dies nicht behoben wurde, aber die Quelle ist offen. Wenn Sie wissen, wie man es löst, würden sie sich sicher über eine Pull-Anfrage freuen.

Das heißt, warum um alles in der Welt ist dieses Thema geschlossen .

Weil es in den beleidigenden Bibliotheken behoben werden sollte. Und die beleidigenden Bibliotheken sehen kein Problem mit der Art und Weise, wie es implementiert wurde.

Also wird es niemand reparieren, weil beide Seiten nicht glauben, dass es kaputt ist.

Sie können ein kleines bisschen dafür beschämt werden 😄

Leute, ich denke, das wurde nicht aus dem einfachen Grund "gelöst", weil es eine extrem schlechte Idee ist, lange Timer zu verwenden.

Wenn Sie in Zukunft Timer im Hintergrund / in Ereignissen ausführen möchten, benötigen Sie dazu eine native Bibliothek. Dies ist auf beiden Plattformen aufgrund von Einschränkungen bei der Hintergrundausführung besonders schwierig.

Basierend auf dem Kommentar von @eightyfive haben wir den Ersatz für die Funktionen rxjs6 delay , timeout & interval reduziert.

Es bleibt noch eine Frage, kann jemand erklären, ob das "Timer-Modul" bei Verwendung kleinerer Intervalle gesperrt bleibt? Grundsätzlich wird der Timer nur angehalten, wenn die App nicht im Vordergrund steht. Oder verbirgt dies nur das Problem?

import { switchMap, concatMap, delay as nativeDelay, mapTo, filter, switchMapTo, repeat } from 'rxjs/operators'
import { range, of, race, throwError, TimeoutError } from 'rxjs'

const TIMER_INTERVAL = 1000
const reactNativeTimer = (duration) => {
  const times = Math.floor(duration / TIMER_INTERVAL)
  const remainder = duration % TIMER_INTERVAL
  if (times < 1) {
    return of(true).pipe(nativeDelay(remainder))
  }
  return range(1, times).pipe(
    concatMap(i => of(i).pipe(nativeDelay(TIMER_INTERVAL))),
    filter(i => i === times),
    nativeDelay(remainder)
  )
}

/**
 * React Native compatible version of delay pipe
 * <strong i="11">@param</strong> {number} duration in ms
 */
export const delay = (duration) => {
  return (source) => {
    return source.pipe(
      switchMap(next =>
        reactNativeTimer(duration).pipe(mapTo(next))
      )
    )
  }
}

/**
 * React Native compatible version of timeout pipe
 * <strong i="12">@param</strong> {number} duration in ms
 */
export const timeout = (duration) => {
  return (source) => {
    const timeoutTimer = reactNativeTimer(duration).pipe(
      switchMapTo(throwError(new TimeoutError()))
    )
    return race(source, timeoutTimer)
  }
}

/**
 * React Native compatible version of interval
 * <strong i="13">@param</strong> {number} duration in ms
 */
export const interval = (duration) => {
  return reactNativeTimer(duration).pipe(
    repeat()
  )
}

Das Lustige daran ist, dass jeder in diesem Thread über eine Problemumgehung spricht, um diese Warnung zu ignorieren.
Als ich von der Warnung zu diesem "Problem" weitergeleitet wurde, hoffte ich, eine geeignete Dokumentation zu finden, in der erklärt wurde, wie? um damit umzugehen und ein bisschen mehr über "warum?" nachzudenken.

Front-End # Millennials

Dieses #millenial möchte darauf hinweisen, dass:

  • Dieser Fehler erfordert keine Dokumentation, ist selbsterklärend: Sie stellen einen langen Timer ein.
  • Dieser Thread ist voll von Leuten, die die Warnung für Bibliotheken stummschalten, die sie nicht besitzen (z. B. Firebase).
  • Wie die (produktive) Diskussion in diesem Thread zeigt, ist dies ein komplexeres Problem, das innerhalb von react-native

Das heißt, ich werde noch einmal darauf hinweisen, dass dieses Problem nicht geschlossen werden sollte, es ist mit known-issue und Help Wanted .

Millenial Antworten auf Millenial :)

Dieser Fehler erfordert keine Dokumentation, ist selbsterklärend: Sie stellen einen langen Timer ein.

  • Es ist kein Fehler, es ist eine Warnung (frag mich nicht nach Unterschieden, sonst müssen wir ein tiefes philosophisches Gespräch beginnen :))
  • Es gibt bereits vor, dokumentiert zu sein, da auf dieses Ticket verwiesen wird, wo ich Tonnen von Kommentaren anstelle von Executive Summary lesen muss (smth wie bekanntes Problem, wie Sie bereits vorgeschlagen haben):
    image
  • Ich würde es nicht "selbsterklärend" sagen. Nicht genügend Kontext bereitgestellt. Eine Beschreibung enthält buchstäblich zwei Sätze.

Das heißt, ich werde noch einmal darauf hinweisen, dass dieses Problem nicht geschlossen werden sollte, es ist als bekanntes Problem und Hilfe gesucht markiert.

Stimme vollkommen zu. Dies spart vielen Personen Zeit, die von der URL-Referenz in der Warnung kommen.

Für Benutzer von Firebase / Firestore: Ich habe einfach wieder die REST-Endpunkte direkt für Firestore-Aufrufe verwendet. Da ich nur Auth und Firestore brauchte, löste das meine Probleme ziemlich leicht. Ausschnitt hier:

https://stackoverflow.com/a/62446792

Ich habe es in App () wie folgt gemacht:

{YellowBox} aus 'react-native' importieren;
Standardfunktion exportieren App () {
YellowBox.ignoreWarnings (['Einstellen eines Timers']);
...
...
..
}}

Erinnern Sie sich

Was ich getan habe und es funktioniert mit mir, aber ich weiß immer noch nicht, ob es eine gute Übung ist oder nicht

Zur Datei navigiert

node_modulesreact-native \ Libraries \ Core \ TimersJSTimers.js

Es gibt eine Funktion const MAX_TIMER_DURATION_MS = 60 * 1000 und ich habe die Zeit auf 60 * 100000 erhöht und sie wurde nicht mehr angezeigt

Sie da,
Dieses Problem ist ungefähr 3 Jahre alt und wir haben immer noch diese Warnung;)
Wie @RWOverdijk sagte, ist das Ignorieren der Warnung keine Lösung.
Gibt es schon eine Lösung, die ich verpasst habe?

Danke <3

Hallo zusammen, wir beschließen, dieses Problem zu beheben. Ich weiß, dass dieses Problem für viele von Ihnen frustrierend ist, und ich möchte mir die Zeit nehmen, um zu verstehen, warum wir diese Entscheidung treffen.

So funktionieren Timer unter Android in React Native

React Native verfügt über eine benutzerdefinierte Implementierung von JS-Timern wie setTimeout . Unter Android funktioniert es so, dass JS-Timer auf der nativen Seite verfolgt werden und die native Seite entscheidet, wann diese Timer ausgelöst werden sollen. Auf diese Weise kann React Native intelligenter darüber sein, wann Timer ausgelöst werden und insbesondere wie sie sich auf den App-Lebenszyklus und das Rendern beziehen.

Was passiert, wenn ich einen Timer mit einem langen Intervall einstelle?

Hier ist mein Verständnis, nachdem ich den Code gelesen und ein wenig getestet habe:

  1. Wenn Sie einen langen Timer einstellen und die App während des aktiven Timers geöffnet bleibt, sollte der Timer weiterhin funktionieren.
  2. Wenn Sie einen langen Timer einstellen und das Telefon vor Ablauf des Timers im Hintergrund ist, wird der Timer erst beim nächsten Öffnen der App aktiviert.
  3. Es gibt eine Ausnahme für kopflose JS-Aufgaben, bei denen Timer auch dann weiterarbeiten können, wenn sich die App im Hintergrund befindet.

Warum sollten wir keine Timer mit langen Intervallen anrufen?

Ich denke, dies ist in erster Linie ein Problem der Korrektheit und weniger der Leistung. Das Problem ist, dass Sie sich nicht auf lange Timer verlassen können, wenn der Benutzer Ihre App im Hintergrund hat.

Wenn es Ihnen nichts ausmacht, Ihren Timer später zu aktivieren, wenn die App wieder im Vordergrund steht, ist es meiner Meinung nach eine gute Idee, die YellowBox-Warnung zu ignorieren.

Wenn Ihr Timer jedoch erwartet, dass er für die Lebensdauer einer Sitzung aufgerufen wird und nicht erneut im Vordergrund ausgelöst wird, müssen Sie etwas tun, um sicherzustellen, dass der Timer im Vordergrund ignoriert wird.

Wie verwende ich Bibliotheken von Drittanbietern wie Socket.io und Firebase, die lange Timer einstellen?

Ich kenne die Details dieser Bibliotheken von Drittanbietern nicht. Letztendlich kommt es auf die obige Frage an. Wenn diese Bibliotheken von Drittanbietern Probleme mit Timern haben, die im Vordergrund gelöst werden, müssen Sie einen Weg finden, dies zu beheben. Einige der obigen Kommentare schlagen beispielsweise Möglichkeiten für Firebase vor. Letztendlich können Sie sich jedoch besser auf eine Bibliothek verlassen, die speziell für React Native entwickelt wurde.

Wenn die Bibliothek eines Drittanbieters jedoch keine Probleme mit der Auflösung von Timern im Vordergrund hat, können Sie den Fehler ignorieren.

Warum kann nicht setTimeout durch AlarmManager , wie ursprünglich vorgeschlagen?

AlarmManager aktiviert die App, wenn sie sich im Hintergrund befindet, und wir glauben nicht, dass Timer wie setTimeout die App aktivieren sollten. Die meisten dieser langen Timer sind auf Zeitüberschreitungen eingestellt, und diese sind nur relevant, wenn die App geöffnet ist. Das Aufwecken einer App im Hintergrund ist teuer und sollte nur durchgeführt werden, wenn der Entwickler dies ausdrücklich beabsichtigt.

Gleichzeitig haben wahrscheinlich viele Menschen ein Bedürfnis nach so etwas. Wir könnten eine API dafür entwickeln, die nicht setTimeout durchläuft. Aufgrund der aktuellen Lean Core-Bemühungen versuchen wir jedoch zu vermeiden, die API-Oberfläche für React Native zu vergrößern. Wir glauben, dass dies eine Aufgabe ist, die am besten von einer Drittanbieter-Bibliothek wie react-native-background-timer erledigt wird.

Warum entfernen Sie die Warnung dann nicht vollständig?

Wir möchten, dass Entwickler wissen, was los ist. Wenn jemand eine Bibliothek installiert, die auf der Richtigkeit von setTimeout beruht, sollte der Entwickler der Meinung sein, dass wir diese Richtigkeit nicht garantieren können. Wir möchten es den einzelnen Entwicklern überlassen, zu entscheiden, ob diese Warnung in ihrem jeweiligen Anwendungsfall von Bedeutung ist.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen