Javascript 创建带有动态超时的承诺

Javascript 创建带有动态超时的承诺,javascript,asynchronous,promise,Javascript,Asynchronous,Promise,我创建了一个Promise,以便在完成一个文件的合成时获得该文件的持续时间 我认为该解决方案的效率确实很低,因为我设置了一个超时时间,无论任务何时完成,所以每次调用该方法时可能都会浪费时间: polly.synthesizeSpeech(params, function (err, data) { if (err) console.log(err, err.stack); else {

我创建了一个
Promise
,以便在完成一个文件的合成时获得该文件的持续时间

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

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
之后,我会得到文件的持续时间,但我希望在文件完成合成后立即这样做。我怎么做呢?

这对你有用吗

基本上,您只需要用一个承诺来包装您希望得到通知的代码。如果您有一个回调函数,就像在您的示例中一样,那么您所要做的就是让它从该回调中解析

const audioFileDuration=(参数)=>新承诺((解析、拒绝)=>{
polly.synthesizeSpeech(参数,函数(错误,数据){
如果(错误){
拒绝(错误);
}
var uInt8Array=新的uInt8Array(data.AudioStream);
var arrayBuffer=uInt8Array.buffer;
var blob=新blob([arrayBuffer]);
var urlAudioFile=URL.createObjectURL(blob);
var audio=新音频(URLAudio文件);
audio.type='audio/wav';
解析(音频。持续时间)
});
});

audioFileDuration(params)。那么(duration=>console.log(duration))
这对您有用吗

基本上,您只需要用一个承诺来包装您希望得到通知的代码。如果您有一个回调函数,就像在您的示例中一样,那么您所要做的就是让它从该回调中解析

const audioFileDuration=(参数)=>新承诺((解析、拒绝)=>{
polly.synthesizeSpeech(参数,函数(错误,数据){
如果(错误){
拒绝(错误);
}
var uInt8Array=新的uInt8Array(data.AudioStream);
var arrayBuffer=uInt8Array.buffer;
var blob=新blob([arrayBuffer]);
var urlAudioFile=URL.createObjectURL(blob);
var audio=新音频(URLAudio文件);
audio.type='audio/wav';
解析(音频。持续时间)
});
});

audioFileDuration(params)。然后(duration=>console.log(duration))
SetTimeOut充当您要等待函数的最大持续时间[TTL]。 您可以尝试在两个流中解析承诺

  • 当超时达到3000毫秒时
  • 一旦您在文件完成合成后获得文件的持续时间
  • 上述任何一个流提前完成都将解决承诺,您的代码可以继续进行,而不必等待第二次解决


    如果第二个过程(获取持续时间)提前完成,请确保清除超时

    SetTimeOut作为要等待函数的最大持续时间[TTL]。 您可以尝试在两个流中解析承诺

  • 当超时达到3000毫秒时
  • 一旦您在文件完成合成后获得文件的持续时间
  • 上述任何一个流提前完成都将解决承诺,您的代码可以继续进行,而不必等待第二次解决


    确保清除超时。如果第二个过程(获取持续时间)提前完成,则可以从文档中获取持续时间:

    var audioElement = new Audio('car_horn.wav');
    audioElement.addEventListener('loadeddata', () => {
      let duration = audioElement.duration;
      // The duration variable now holds the duration (in seconds) of the audio clip 
    })
    

    希望它能帮助您

    从文档中,似乎可以获得持续时间:

    var audioElement = new Audio('car_horn.wav');
    audioElement.addEventListener('loadeddata', () => {
      let duration = audioElement.duration;
      // The duration variable now holds the duration (in seconds) of the audio clip 
    })
    

    希望对您有所帮助

    您为什么需要在此处暂停?如果处理速度太慢(超过3秒),是否要
    拒绝
    承诺?不,我只想获得音频的值。持续时间一旦可用,请查看@arge的答案,这是正确的。为什么需要在此超时?如果处理速度太慢(超过3秒),是否要
    拒绝
    承诺?不,我只想获得音频的值。持续时间一旦可用,请查看@Argee的答案,当我在代码中运行它时,它是正确的,打印的消息是NaN,这意味着仍然没有文件。当我在代码中运行它时,打印的消息是NaN,这意味着仍然没有文件