Javascript 为什么在使用handlebackpress方法进行控制台操作时,即使在执行clearInterval之后,计时器也不会回到零位?如何避免丢失帧

Javascript 为什么在使用handlebackpress方法进行控制台操作时,即使在执行clearInterval之后,计时器也不会回到零位?如何避免丢失帧,javascript,react-native,Javascript,React Native,我试图自动启动视频,但在此之前,实现计时器并清除计时器是我的目标。倒计时正在被清除,但即使在被清除后,处于“我的设置间隔”被分配状态的计时器仍会继续增加。此外,在每次切换时都会有大量的帧丢失和口吃,即使我的代码变得太混乱,我也非常感谢任何帮助,帮助我改进我的混乱代码并避免丢失的帧 多谢各位 import React, { Component } from 'react'; import { Platform, StyleSheet,

我试图自动启动视频,但在此之前,实现计时器并清除计时器是我的目标。倒计时正在被清除,但即使在被清除后,处于“我的设置间隔”被分配状态的计时器仍会继续增加。此外,在每次切换时都会有大量的帧丢失口吃,即使我的代码变得太混乱,我也非常感谢任何帮助,帮助我改进我的混乱代码并避免丢失的帧

多谢各位

        import React, { Component } from 'react';
        import {
        Platform,
        StyleSheet,
        Text,
        BackHandler,
        TouchableOpacity,
        View,
        Alert,
        PermissionsAndroid,
        CameraRoll,
        } from 'react-native';
        import { RNCamera } from 'react-native-camera';
        import RNFetchBlob from 'rn-fetch-blob';

        const url = 'MY API';

        export default class App extends Component {

        constructor() {
            super();
            this.state = {
            showCamera: false,
            cameraType: RNCamera.Constants.Type.front,
            recording: false,
            timer: null,
            count: null
            };
        }

        componentDidMount() {
            this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
            this.permissionRequest();
        }

        componentWillUnmount() {
            this.backHandler.remove();
        }

        async permissionRequest() {
            try {
            const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
            {
                'title': 'Require Permission for Storage',
                'message': 'Storage permisson is required to store your photos in the gallery'
            });

            if (granted === PermissionsAndroid.RESULTS.GRANTED) {
                console.log('granted', PermissionsAndroid.RESULTS);
            } else {
                console.warn('denied', PermissionsAndroid.RESULTS);
            }
            } catch (err) {
            console.warn('err', err);
            }
        }

        handleBackPress = async () => {
            if (this.state.showCamera === true) {
            await this.setState({ showCamera: false });
            clearInterval(this.state.timer);
            console.log('this.state.timer', this.state.timer);
            // this.setState({ count: null });
            console.log('this.state.timer after', this.state.timer, this.state.count);
            } else {
            BackHandler.exitApp();
            }
        }

        async toggleCamera() {
            // console.log(this,'this');
            await this.setState({ showCamera: !this.state.showCamera });
            console.warn(this.state.showCamera, 'checking status');
            if (this.state.showCamera === true) {
            this.setState({ count: 10 });
            let timer = setInterval(this.tickingTimer, 1000);
            this.setState({ timer });
            }
        }

        tickingTimer = () => {
            if (this.state.count > 0) {
            this.setState({ count: this.state.count -1 });
            console.log(this.state.count);
            }
        }

        async takePicture() {
            if (this.camera) {
            const options = { quality: 0.9, base64: true };
            const data = await this.camera.takePictureAsync(options);
            CameraRoll.saveToCameraRoll(data.uri)
                .then(resp => {
                console.log('resp', resp);
                })
                .catch(err => {
                console.log('err', err);
                });
            console.log(data);
            }
        }

        async recordVideo() {
            if (this.camera) {
            this.setState({ recording: true });
            const options = { quality: 'RNCamera.Constants.VideoQuality.480p', maxDuration: 2 };
            const {uri, codec = 'mp4' } = await this.camera.recordAsync(options);
            this.setState({ recording: false });
            const type = `video/${codec}`;
            CameraRoll.saveToCameraRoll(uri)
                .then(resp => {
                console.log('video resp', resp)
                })
                .catch(err => {
                console.log('err Video', err);
                })

                RNFetchBlob.fetch('POST', url + 'upload', {
            }, 
            [
                {
                name: 'file',
                filename: 'filename.mp4',
                data: RNFetchBlob.wrap(uri),
                type
                }
            ]
            )
            .uploadProgress({ interval : 200 }, (written, total) => {
            console.log('progress', written, total, written / total)
            })
            .then(res => JSON.parse(res.data))
            .then((res) => {
                console.log(' server', res.file.URL);
            })
            .catch((err) => {
                console.log('error ', err);
            });
            }
        }

        async stopVideo() {
            if (this.camera) {
            await this.camera.stopRecording();
            this.setState({ recording: false });
            } 
        }

        swapCamera() {
            const { cameraType } = this.state;
            let newType;
            if (this.camera) {
            cameraType === RNCamera.Constants.Type.front ? newType = RNCamera.Constants.Type.back : newType = RNCamera.Constants.Type.front;
            }
            this.setState({ cameraType: newType });
        }

        render() {
            const { showCamera, recording, cameraType, count } = this.state;
            return (
            <View style={styles.container}>
                {
                    showCamera === false ? 
                        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                        <TouchableOpacity style={{ height: 50, width: 80, marginVertical: 5, justifyContent: 'center', alignItems: 'center', borderRadius: 5, backgroundColor: 'rgba(52,130,116,0.9)' }} onPress={() => this.toggleCamera()}>
                            <Text style={{ color: 'white', textAlign: 'center' }}>Open Camera</Text>
                        </TouchableOpacity>

                        <TouchableOpacity style={{ height: 50, width: 80, marginVertical: 5, justifyContent: 'center', alignItems: 'center', borderRadius: 5, backgroundColor: 'rgba(52,130,116,0.9)' }} onPress={() => this.toggleCamera()}>
                            <Text style={{ color: 'white', textAlign: 'center' }}>Record Video</Text>
                        </TouchableOpacity>
                        </View> 
                        :  
                        <RNCamera style={{ flex: 1, alignItems: 'center', justifyContent: 'flex-end' }} ref={ref => { this.camera = ref }} flashMode={RNCamera.Constants.FlashMode.auto} captureAudio = {true} type={cameraType}>
                        <View style={{ flexDirection: 'row', marginVertical: 20 }}>
                            <View style={{ flex: 0.3, justifyContent: 'center', alignItems: 'center' }}>
                                <Text style={{ color: 'white' }}>starts in <Text style={{color: 'red', fontWeight: 'bold', fontSize: 16 }}>{count}</Text></Text>
                            </View>
                            <View style={{ flex: 0.3, justifyContent: 'center', alignItems: 'center' }}>
                            <View style={{ height: 60, width: 60, marginHorizontal: 5, borderRadius: 30, padding: 5, borderWidth: 2, borderColor: 'white' }}>
                                {recording === false ? 
                                    <TouchableOpacity disabled={this.state.count !== 0} onPress={() => this.recordVideo()} style={{ flex: 1, borderRadius: 30, backgroundColor: 'white', alignItems: 'center', justifyContent: 'center' }} /> : 
                                    <TouchableOpacity onPress={() => this.stopVideo()} style={{ flex: 1, borderRadius: 30, backgroundColor: 'red', alignItems: 'center', justifyContent: 'flex-end' }} />
                                }
                            </View>
                            </View>
                            <View style={{ flex: 0.4 }}>
                                <TouchableOpacity onPress={() => this.swapCamera()} style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                                    <Text style={{ color: 'white' }}>Swap</Text>
                                </TouchableOpacity>
                            </View>
                        </View>
                        </RNCamera>
                        }
            </View>
            );
        }
        }

const styles = StyleSheet.create({
        container: {
            flex: 1,
            backgroundColor: '#F5FCFF',
        },
        welcome: {
            fontSize: 20,
            textAlign: 'center',
            margin: 10,
        },
        instructions: {
            textAlign: 'center',
            color: '#333333',
            marginBottom: 5,
        },
        capture: {
            flex: 0,
            backgroundColor: '#fff',
            borderRadius: 5,
            padding: 15,
            paddingHorizontal: 20,
            alignSelf: 'center',
            margin: 20
        }
        });

// This is my package.json file
   {
    "name": "newApp",
    "version": "0.0.1",
    "private": true,
    "scripts": {
        "start": "node node_modules/react-native/local-cli/cli.js start",
        "test": "jest"
    },
    "dependencies": {
        "react": "16.3.1",
        "react-native": "0.55.4",
        "react-native-camera": "git+https://git@github.com/react-native-community/react-native-camera",
        "react-native-easy-toast": "^1.1.0",
        "react-native-progress-circle": "^2.0.0",
        "rn-fetch-blob": "^0.10.13"
    },
    "devDependencies": {
        "babel-jest": "22.4.4",
        "babel-preset-react-native": "4.0.0",
        "jest": "22.4.4",
        "react-test-renderer": "16.3.1"
    },
    "jest": {
        "preset": "react-native"
    }
    }
import React,{Component}来自'React';
进口{
平台,
样式表,
文本,
后台处理程序,
可触摸不透明度,
看法
警觉的,
许可证Sandroid,
摄影师,
}从“反应本机”;
从“react native camera”导入{RNCamera};
从“rn fetch blob”导入RNFETCH blob;
consturl='myapi';
导出默认类应用程序扩展组件{
构造函数(){
超级();
此.state={
摄像机:错,
cameraType:RNCamera.Constants.Type.front,
录音:错,
计时器:空,
计数:空
};
}
componentDidMount(){
this.backHandler=backHandler.addEventListener('hardwareBackPress',this.handleBackPress');
此.permissionRequest();
}
组件将卸载(){
this.backHandler.remove();
}
异步许可请求(){
试一试{
const grated=wait PERMISSIONS和roid.request(PERMISSIONS和roid.PERMISSIONS.WRITE\u外部存储、,
{
“标题”:“需要存储权限”,
“消息”:“在库中存储照片需要存储许可证”
});
如果(已授予===权限sandroid.RESULTS.已授予){
console.log('prograted',PermissionsAndroid.RESULTS);
}否则{
console.warn('denied',PermissionsAndroid.RESULTS);
}
}捕捉(错误){
console.warn('err',err);
}
}
handleBackPress=async()=>{
if(this.state.showCamera===true){
等待此.setState({showCamera:false});
clearInterval(this.state.timer);
log('this.state.timer',this.state.timer);
//this.setState({count:null});
log('this.state.timer after',this.state.timer,this.state.count);
}否则{
BackHandler.exitApp();
}
}
异步切换摄影机(){
//log(this,'this');
等待此.setState({showCamera:!this.state.showCamera});
console.warn(this.state.showCamera,“检查状态”);
if(this.state.showCamera===true){
this.setState({count:10});
让定时器=设置间隔(this.tickingTimer,1000);
this.setState({timer});
}
}
滴答时间=()=>{
如果(this.state.count>0){
this.setState({count:this.state.count-1});
console.log(this.state.count);
}
}
异步takePicture(){
如果(这个相机){
const options={quality:0.9,base64:true};
const data=wait this.camera.takePictureAsync(选项);
CameraRoll.saveToCameraRoll(data.uri)
。然后(resp=>{
控制台日志('resp',resp);
})
.catch(错误=>{
console.log('err',err);
});
控制台日志(数据);
}
}
异步录制视频(){
如果(这个相机){
this.setState({recording:true});
const options={quality:'RNCamera.Constants.VideoQuality.480p',maxDuration:2};
const{uri,codec='mp4'}=wait this.camera.recordAsync(选项);
this.setState({recording:false});
const type=`video/${codec}`;
CameraRoll.saveToCameraRoll(uri)
。然后(resp=>{
console.log('video resp',resp)
})
.catch(错误=>{
console.log('err Video',err);
})
RNFetchBlob.fetch('POST',url+'upload'{
}, 
[
{
名称:'文件',
filename:'filename.mp4',
数据:RNFetchBlob.wrap(uri),
类型
}
]
)
.uploadProgress({interval:200},(已写入,总计)=>{
console.log(‘进度’、已写入、总计、已写入/总计)
})
.then(res=>JSON.parse(res.data))
。然后((res)=>{
log('server',res.file.URL);
})
.catch((错误)=>{
console.log('error',err);
});
}
}
异步停止视频(){
如果(这个相机){
等待此消息。照相机。停止录制();
this.setState({recording:false});
} 
}
swapCamera(){
const{cameraType}=this.state;
让新类型;
如果(这个相机){
cameraType===RNCamera.Constants.Type.front?newType=RNCamera.Constants.Type.back:newType=RNCamera.Constants.Type.front;
}
this.setState({cameraType:newType});
}
render(){
const{showCamera,recording,cameraType,count}=this.state;
返回(
{
showCamera==假?
this.setState({ showCamera: false }, () => {
  clearInterval(this.timer);
});