Javascript 问题:如何从此处显示的函数返回所需的 url:
function getAudioBlob() {
return recorder && recorder.exportWAV(function (blob) {
var url = URL.createObjectURL(blob);
console.log(url) // works great!
return url;
}, ("audio/mp3"));
}
console.log(getAudioBlob()); // the log reads 'undefined'
我在获取从此函数返回的 URL 字符串(用于音频 blob)时遇到问题。我的目标是能够使用 Blob Url 将录音上传到服务器。
我的问题源于我不知道如何从这种尴尬的安排中获取返回的值:
recorder && recorder.exportWAV(function (blob) {...
我在它前面放了一个“return”,但这显然不起作用。我该如何重写它呢?谢谢!
最佳答案
exportWAV 是异步的,因此它会在您的函数执行后完成。您可以在准备就绪时使用回调或 Promise 运行一些代码。 .例如:
function getAudioBlob(recorder) {
return new Promise((resolve) => {
recorder.exportWAV((blob) => {
const url = URL.createObjectURL(blob);
resolve(url);
}, 'audio/mp3');
});
}
// Use the function..
if (recorder) {
getAudioBlob(recorder).then(url => console.log('blob url:', url));
}
完成 url 后,您应该调用 URL.revokeObjectURL(url)
来释放内存。
我很关心您所说的“我的目标是能够使用 Blob Url 将录音上传到服务器”的意思。您创建的 URL 仅适用于该客户,并且仅在该选项卡打开时存在。
下面是针对您的整个问题的一些 PoC 代码:
// This is a shorthand for writing a function that returns something.
const getAudioBlob = recorder =>
new Promise(resolve => recorder.exportWAV(resolve, 'audio/mp3'));
function uploadBlobToServer(blob) {
const fd = new FormData();
fd.append('recording', blob, 'recording.mp3');
return fetch('/api/recording/upload', { method: 'POST', body: fd });
}
function stopRecording() {
if (!recorder) {
console.error('No recorder found');
return;
}
recorder.stop();
getAudioBlob(recorder).then((blob) => {
// Not sure what this is but guessing it needs to be called
// AFTER exportWAV has finished?
recorder.clear();
// When we return a Promise inside another, the subsequent .then()/.catch()
// Will have the result of this promise (in this case the result of the upload).
return uploadBlobToServer(blob);
})
.then((res) => {
if (res.status > 400) {
throw new Error(res.statusText);
}
})
.then((res) => {
console.log('Recording uploaded to server successfully.', res.status, res.statusText);
})
.catch((error) => {
console.error('Failed to upload recording to server.', error);
});
}
// Or this is how you could write that function using asyc/await which is a bit cleaner
// than using the Promises directly, but it's only supported by new browser versions.
async function stopRecording() {
if (!recorder) {
console.error('No recorder found');
return;
}
recorder.stop();
try {
const blob = await getAudioBlob(recorder);
const res = await uploadBlobToServer(blob);
// The HTTP Status code from the server was an error.
if (res.status > 400) {
throw new Error(res.statusText);
}
console.log('Recording uploaded to server successfully.', res.status, res.statusText);
recorder.clear();
} catch (error) {
console.error('Failed to create and upload your recording:', error);
}
}
关于javascript - 从复杂函数返回字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49560619/