Safari: Promise "syntaxError: Unexpected keyword 'function'. Expected ')' "

Safari: Promise "syntaxError: Unexpected keyword 'function'. Expected ')' "

此代码在 Chrome 中有效,但在第 2 行中因 Safari 中的主题语法错误而失败。 此外,在 iOS 中,Safari 用户被要求获得使用麦克风的权限,但录音失败。 Android Chrome.

一切顺利

Fiddle shows more

Code is based on

index.js:

var recordAudio = function recordAudio() {
  return new Promise(async function(resolve) {
    var stream = await navigator.mediaDevices.getUserMedia({
      audio: true
    });
    var mediaRecorder = new MediaRecorder(stream);
    var audioChunks = [];
    mediaRecorder.addEventListener("dataavailable", function(event) {
      audioChunks.push(event.data);
    });

    var start = function start() {
      audioChunks = [];
      mediaRecorder.start();
    };

    var stop = function stop() {
      return new Promise(function(resolve) {
        mediaRecorder.addEventListener("stop", function() {
          var audioBlob = new Blob(audioChunks);
          var audioUrl = URL.createObjectURL(audioBlob);
          var audio = new Audio(audioUrl);

          var play = function play() {
            return audio.play();
          };

          resolve({
            audioChunks: audioChunks,
            audioBlob: audioBlob,
            audioUrl: audioUrl,
            play: play
          });
        });
        mediaRecorder.stop();
      });
    };

    resolve({
      start: start,
      stop: stop
    });
  });
};

您正在混合使用 Promiseasync 语法,Safari 的错误告诉您它不需要 async 函数,这对您来说很有意义用另一个承诺解决一个承诺。

function recordAudio 更改为 async function recordAudio 并完全删除 new Promise,只使用 await

任何使用 await 的函数都会 return 一个 Promise

async function recordAudio() {
    var stream = await navigator.mediaDevices.getUserMedia({
      audio: true
    });
    var mediaRecorder = new MediaRecorder(stream);
    var audioChunks = [];
    mediaRecorder.addEventListener("dataavailable", function(event) {
      audioChunks.push(event.data);
    });

    var start = function start() {
      audioChunks = [];
      mediaRecorder.start();
    };

    var stop = function stop() {
      return new Promise(function(resolve) {
        mediaRecorder.addEventListener("stop", function() {
          var audioBlob = new Blob(audioChunks);
          var audioUrl = URL.createObjectURL(audioBlob);
          var audio = new Audio(audioUrl);

          var play = function play() {
            return audio.play();
          };

          resolve({
            audioChunks: audioChunks,
            audioBlob: audioBlob,
            audioUrl: audioUrl,
            play: play
          });
        });
        mediaRecorder.stop();
      });
    };

    return {
      start: start,
      stop: stop
    };
};

在 Safari 10.1 中添加了对 async 功能的支持。您在 9.1 中进行测试,它太旧了。

如果您需要您的应用程序与这样一个旧的 Safari 版本(从 2016 年开始)兼容,您将必须使用显式 Promise 代码而不是 asyncawait .