0

我正在制作录音机,我正在使用 promise async 来学习 async 。

这是我的代码,一次调用可以正常工作,但是一旦我在函数handleAction结束时递归调用函数,它就会开始表现得很奇怪。

我不知道为什么,但代码在 Snippet 上不起作用。

如果我不在handlefunction函数的末尾调用handleAction()函数,它工作正常

const recordAudio = () =>
    new Promise(async resolve => {
        const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); //it return a promise that resolves to a mediastream object.
        const mediaRecorder = new MediaRecorder(stream); // provide functionality to easily record media 
        //mediastream interface represent a stream of media content . A stream consists of several tracks such as videa nad audio
        const audioChunks = [];

        mediaRecorder.addEventListener('dataavailable', event => {
            audioChunks.push(event.data);
        });

        const start = () => mediaRecorder.start();

        const stop = () =>

            new Promise(async resolve => {
                mediaRecorder.addEventListener('stop', () => {

                    const audioblob = new Blob(audioChunks);
                    // const audioChunks = [];
                    const audioURL = URL.createObjectURL(audioblob);
                    const audio = new Audio(audioURL);
                    const play = () => audio.play();
                    resolve({ audioblob, audioURL, play });

                });

                mediaRecorder.stop();

                // set the mediarecorder.state to "inactive" and stop capturing media raise a dataavailable evenet containing the bolb of data that has been gathered 
            });

        resolve({ start, stop });

    });


const later = (delay, value) => {
    let timer = 0;
    let reject = null;
    const promise = new Promise((resolve, _reject) => {
        reject = _reject;
        timer = setTimeout(resolve, delay, value);
    });

    return {
        get promise() {

            return promise;

        },


        cancel() {
            if (timer) {
                clearTimeout(timer);
                timer = 0;
                reject();
                reject = null;
            }

        }
    };
};

const sleep = time => new Promise(resolve => setTimeout(resolve, time));

var audio = "";
var recorder = "";
const handleAction = async () => {

    const data_rep = document.getElementById('loop-number-input').value * 1000;
    const actionButton = document.getElementsByClassName('record_button_inside');
    const color_change = document.getElementsByClassName('record_button_inside')[0];
    const actionButton_p = document.getElementsByClassName('state_info')[0];
   
    actionButton.disabled = true;
    color_change.style.background = 'red';
    actionButton_p.innerText = "RECORDING";
  
    var element = document.getElementById('myBar');
    var width = 1;
    recorder = await recordAudio(); 
    recorder.start(); 
    var id = setInterval(frame, document.getElementById('loop-number-input').value * 10); 
    await sleep(data_rep);   
         
    // this is display bar to show how much time left for recording

    function frame() {
        if (width >= 100) {
            console.log("entered");
            clearInterval(id);
            width = 1;
        } else {
            width++;
            element.style.width = width + '%';

        }
    }

    audio = await recorder.stop();
    audio.play();
    var id2 = setInterval(frame_after, document.getElementById('loop-number-input').value * 9.5);


    // this is bar to display the percentage of sound played 
    function frame_after() {
        var element = document.getElementById('myBar');
        element.style.background = 'red';
       
        if (width >= 100) {
            console.log("entered");
            clearInterval(id2);
            element.style.width = 1;

        } else {

            width++;
            element.style.width = width + '%';

        }
    }


    actionButton_p.innerText = "playing !!!!";
    color_change.style.background = 'inherit';
    actionButton.disabled = false;
    // if(document.getElementById('loopcheck').checked){
   handleAction();
    // }

}
body{
	background: #e4b60c !important;
	height: 100vh;

}

h1.title{
	font-family: 'Roboto', sans-serif !important;
	padding-bottom: 12px ;
	border-bottom: 1px solid #5a5a5a40;

}

#loop-number-input{
box-shadow: 0 2px 5px 0 rgba(0,0,0,0.16), 0 2px 10px 0 rgba(0,0,0,0.12);
}

.record_button_inside  {
	background-color: #673AB7;
	padding: 10px;
	border-radius: 50%;
	width: 60px;
	height: 60px;
	border-color: transparent;
	color: white;
	font-size: 26px;
	box-shadow: 0 2px 5px 0 rgba(0,0,0,0.16), 0 2px 10px 0 rgba(0,0,0,0.12);
}

.replay_button{
	float: right;
	width: 40px;
	height: 40px;
	font-size: 20px;
	padding: inherit;
}

.record_button_inside:focus {

	/*background-color: transparent;*/
	border: none;
}


.padd {
	margin: 30px 0px;
}
.recorder_div{
	position: relative;
	top: 25%;
	/*height: 100vh;*/
}

.recorder_div div  ,h1 , p {
	position: relative;
	top: 25%;
	
}

#myProgress {
  width: 100%;
  background-color: #ddd;
}

#myBar {
  width: 1%;
  height: 30px;
  background-color: #4CAF50;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="container">
        <div class="row">
            <div class="col-sm-12">
                <div class="recorder_div">
                    <h1 class="title">Audio Recording Test</h1>
                    <div class="form-group row padd ">
                        <label for="example-number-input" class="col-3 col-form-label">Enter the time for the loop (default is 5 seconds)</label>
                        <div class="col-6">
                            <input class="form-control" type="number" value="5" id="loop-number-input" style="max-width: 250px;margin-bottom: 30px;">
                        </div>
                    </div>
                    <div class="form-check form-check-inline">
                        <input class="form-check-input" type="checkbox" id="loopcheck" value="option1">
                        <label class="form-check-label" for="inlineCheckbox1">Check for auto play and record continously </label>
                    </div>
                    <p>sing for input loop seconds, then you will hear your recording played back</p>
                    <div>
                        <button class="record_button_inside" id="action" onclick="handleAction()">
                            <i class="fas fa-microphone-alt"></i>
                        </button>
                        <!-- <button class="record_button_inside replay_button" id="action" onclick="handleAction('False')">
                          <i class="fas fa-redo-alt"></i>
                        </button> -->
                        <hr />
                        <div id="myProgress">
                            <div id="myBar"></div>
                        </div>
                        <p class="state_info">Start recording...</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

4

1 回答 1

0

这是因为,您的handleAction()函数是一个异步函数。最后,试着这样称呼它:

return await handleAction();

希望这可以帮助 :)

于 2019-08-07T19:42:19.557 回答