首页 > 解决方案 > 承诺冻结浏览器直到 .then 被调用

问题描述

    this.testfunction = function (file) {

        var bufferPromise = new Response(file).arrayBuffer();
        bufferPromise.then(function (buffer) {
            //do stuff
        });
    };

我有一个方法需要从 File 对象中检索数据(https://developer.mozilla.org/en-US/docs/Web/API/File

arrayBuffer() 创建一个承诺,然后我使用 then 基于该承诺执行我的其余代码。

不幸的是,在“then”被触发之前,我的浏览器冻结了。该方法已结束,但在承诺通过之前,我仍然无法按下任何其他按钮。为什么?

编辑:

    <input id="files" class="hidden" type="file" data-bind="event: { change: function() { testfunction($element.files[0]) } }, click: $element.value=null;">
                

该方法由输入上的敲除绑定触发。该文件来自输入。

标签: javascriptpromise

解决方案


我对Response直接使用这样的作品感到有点惊讶。:-)

除了使用该Response对象,您有几个选择:

  1. 在现代环境中,File对象本身有一个可以使用的arrayBuffer方法继承自它。Blob

  2. 在稍微不那么现代的环境中,您可以使用FileReader'readAsArrayBuffer方法。

这是#1的示例:

document.querySelector("input").addEventListener("change", function() {
    const [file] = this.files;
    if (file) {
        console.log("Reading...");
        file.arrayBuffer()
        .then(data => {
            console.log(`Read ${data.byteLength} bytes`);
        })
        .catch(error => {
            console.error(error);
        });
    }
});
<input type="file">

这不会在读取文件时阻塞主 UI 线程。(只是检查确定。)(也就是说,我尝试使用Response但它也没有......)


推荐阅读