在 svelte 中,如何将异步函数绑定到属性?
In svelte, how to bind an async function to an attribute?
在我的代码中,
我有一张图片 class,图片 class 加载一张图片作为数据 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>
我试过了
await 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));
});
};
}
}
image.load()
returns 承诺,因此您需要在渲染循环中使用 #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>
在我的代码中,
我有一张图片 class,图片 class 加载一张图片作为数据 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>
我试过了
await 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));
});
};
}
}
image.load()
returns 承诺,因此您需要在渲染循环中使用 #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>