首页 > 解决方案 > 创建具有动态超时的承诺

问题描述

我创建了一个Promisein oder 来获取一个文件的持续时间,只要它完成了它的合成。

我相信该解决方案确实效率低下,因为timeout无论任务何时完成我都设置了一个,所以每次调用该方法时我可能只会浪费时间:

polly.synthesizeSpeech(params, function (err, data) {
            if (err)
                console.log(err, err.stack);
            else {
                var uInt8Array = new Uint8Array(data.AudioStream);
                var arrayBuffer = uInt8Array.buffer;
                var blob = new Blob([arrayBuffer]);

                var urlAudioFile = URL.createObjectURL(blob);

                var audio = new Audio(urlAudioFile);
                audio.type = 'audio/wav';
                getAudioFileDurationAsync(audio);

            };
        });

 function getAudioFileDurationAsync(audio) {
        let promise = new Promise(function (resolve, reject) {

            setTimeout(() => {
                resolve("done!")
            }, 3000);
        });

        promise.then(
            result => {
                console.log(audio.duration);
            }, 
            error => console.log(error) // doesn't run
        );
    };

显然,在3000ms我得到文件的持续时间之后,但我想在文件完成合成后立即进行。我怎么能做到?

标签: javascriptasynchronouspromise

解决方案


这对你有用吗?

基本上你只需要用 Promise 包装你想要通知的代码。如果您像示例中那样有一个回调函数,那么您所要做的就是让它从该回调中解析。

const audioFileDuration = (params) => new Promise((resolve, reject) => {

  polly.synthesizeSpeech(params, function(err, data) {
    if (err) {
      reject(err);
    }
    var uInt8Array = new Uint8Array(data.AudioStream);
    var arrayBuffer = uInt8Array.buffer;
    var blob = new Blob([arrayBuffer]);

    var urlAudioFile = URL.createObjectURL(blob);

    var audio = new Audio(urlAudioFile);
    audio.type = 'audio/wav';

    resolve(audio.duration)
  });
});

audioFileDuration(params).then(duration => console.log(duration))


推荐阅读