简而言之,如何将异步函数绑定到属性?

时间:2020-11-06 20:00:23

标签: svelte

在我的代码中,

我有一个图像类,该图像类将图像作为数据URL加载。

    class Image {
    constructor(name, file, timestamp) {
        this.name = name;
        this.file = file;
        this.timestamp = timestamp;
    }

    async load() {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(this.file);
            reader.onload = (readerEvent) => {
                resolve(readerEvent.target.result);
            };
        });
    }
}

let images = []; // an array of class Image

然后我要渲染图像,但是似乎没有调用image.load函数。

<div class="navbar">
    {#each images as image}
        <li><img bind:this={image} alt={image.name} src={image.load} /></li>
    {/each}
</div>

我尝试过

等待image.load()//无法编译

image.load()//可以编译,但是不起作用。

他们不起作用

这就是我初始化数组的方式

function openFiles() {
    if (window.indexedDB) {
        let db = await (async () => {
            return new Promise((resolve, reject) => {
                let request = window.indexedDB.open("DirHandle", 1);
                request.onerror = function (event) {
                    console.log("request error: ", request.errorCode);
                    reject(request.errorCode);
                };
                request.onsuccess = function (event) {
                    console.log("request success!");
                    let db = event.target.result;
                    db.onerror = function (event) {
                        console.log("db err:", event.target.errorCode);
                        reject(event.target.errorCode);
                    };
                    resolve(db);
                };
                request.onupgradeneeded = function (event) {
                    console.log("need to init");
                    let db = event.target.result;
                    let objectStore = db.createObjectStore("dir", {
                        autoIncrement: true,
                    });
                };
            });
        })();
        var transaction = db.transaction(["dir"], "readwrite");
        // Do something when all the data is added to the database.
        transaction.oncomplete = function (event) {
            console.log("transaction All done!");
        };

        transaction.onerror = function (event) {
            // Don't forget to handle errors!
            console.log("transaction error");
        };

        let dirStore = transaction.objectStore("dir");
        let request = dirStore.get(10);
        request.onsuccess = async function (event) {
            console.log("loaded!");
            dirhandle = request.result;
            const opts = {};
            opts.mode = "readwrite";
            if ((await dirhandle.queryPermission(opts)) === "granted") {
                console.log("permission granted already");
            } else {
                console.log("not granted already when loading");
                try {
                    if (
                        (await dirhandle.requestPermission(opts)) ===
                        "granted"
                    ) {
                    } else {
                        console.log("failed to get permissions");
                    }
                } catch (e) {
                    console.log("e", e);
                }
            }

            for await (const entry of dirhandle.values()) {
                    console.log(
                        entry.kind,
                        entry.name,
                        await entry.getFile()
                    );
                    files.set(entry.name, await entry.getFile());
                }
                images = [];
                files.forEach((value, key, map) => {
                    images.push(new Image(key, value, value.timestamp));
            });
        };
    }
}

1 个答案:

答案 0 :(得分:0)

image.load()返回一个Promise,因此您需要在渲染循环中使用#await块:

<div class="navbar">
    {#each images as image}
        <li>
            {#await image.load()}
                <span>{`Loading ${image.name}...`}</span>
            {:then src}
                <img bind:this={image} alt={image.name} {src} />
            {:catch error}
                <span>{`Error loading ${image.name}: ${error.message}`}
            {/await}
        </li>
    {/each}
</div>