LocalForage、图像和 Blob
LocalForage, images and Blobs
我对 LocalForage 的使用有点困惑。
我只想从 LocalForage 保存和检索图像,这是我的做法。
function preload() {
localforage.setDriver(localforage.LOCALSTORAGE).then(function() {
lcl_images[0] = new Object();
lcl_images[0].key = 'lclstorage_1';
lcl_images[0].value = 'http://www.superga.com/tcnimg/S/02/S009TE0/XBS009TE0___949______.jpg';
lcl_images[1] = new Object();
lcl_images[1].key = 'lclstorage_2';
lcl_images[1].value = 'https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/2150fb35419617.56f6327b44e47.gif';
for (var i = lcl_images.length - 1; i >= 0; i--) {
var valore = lcl_images[i].value;
localforage.setItem(lcl_images[i].key, lcl_images[i].value, function() {
console.log('Saved: ' + valore);
});
}
});
}
function use_preloaded_image() {
for (var i = lcl_images.length - 1; i >= 0; i--) {
var key = lcl_images[i].key;
localforage.getItem(lcl_images[i].key, function(err, readValue) {
console.log('Read: ', readValue);
document.getElementById(key).src = readValue;
});
}
}
关键是,我不知道使用图像的方法是否正确:我将它们存储为字符串,localForage应该使用parse
和stringify
。
这个例子工作正常(当我离线时,我刷新页面,本地存储中的图像是可见的),但我看到有人使用图像对象或 Blob(我从未听说过,并且即时搜索并没有告诉我太多相关信息)。
其他人发出 XHR 请求下载图像,然后保存它。
我可以考虑使用XHR请求来检查图片是否已经下载。这样对吗?
其次:有人说用blob存储更好。为什么?
请帮助我,谢谢。
编辑(多重承诺)
当我检索图像时,我必须将每个图像绑定到一个 <img>
。但我不知道该怎么做,有承诺。因为在使用 Promise.all()
时我不能使用 for
循环(所以没有索引将图像 src 与图像 id 绑定)。
var promises = [];
for (var i = lcl_images.length - 1; i >= 0; i--) {
promises.push(localforage.getItem(lcl_images[i].key));
}
Promise
.all(promises)
.then(function(value) {
console.log(value);
})
.catch(function(error) {
console.log(error);
});
for (var i = lcl_images.length - 1; i >= 0; i--) {
document.getElementById(lcl_images[i].key).src = value;
}
Promise
.all(promises)
.then(function(value) {
console.log(value);
document.getElementById(lcl_images[i].key).src = value;
// I can't get the index i, no way to set <img> src for id attribute
})
.catch(function(error) {
console.log(error);
});
FIX Promise.all().then()
Promise
.all(promises)
.then(function(value) {
console.log(value);
for (var i = lcl_images.length - 1; i >= 0; i--) {
document.getElementById(lcl_images[i].key).src = value[i];
};
})
Blob 更好,因为 IndexedDB 可以优化它们在磁盘上的存储。本质上,它将它们直接存储为文件句柄。 (在不支持 Blob 或不支持 IDB 的情况下,LocalForage 将转换为 base64。)
要将图像下载为 Blob,最简单的方法是使用获取 polyfill 或 fetch()
API 并使用 response.blob()
(参见 MDN docs)。另一种方法是使用 XMLHttpRequest 并执行 xhr.responseType = 'blob
。示例:
fetch('http://example.com/myimage.gif').then(function (response) {
return response.blob();
}).then(function (blob) {
console.log("yay I have a blob", blob);
}).catch(console.log.bind(console))
您还应该知道的另一件事是,您似乎在代码中犯了一个典型的 Promise 错误,即在 forEach()
循环中执行多个 Promise。您可能更愿意 Promise.all()
。请阅读 We have a problem with promises 了解更多详情。
要使用 Blob,您可以查看 blob-util, which has a tutorial, or you can read the PouchDB guide to attachments。 (PouchDB 使用与 LocalForage 类似的 Blob,因此建议类似。)
我对 LocalForage 的使用有点困惑。 我只想从 LocalForage 保存和检索图像,这是我的做法。
function preload() {
localforage.setDriver(localforage.LOCALSTORAGE).then(function() {
lcl_images[0] = new Object();
lcl_images[0].key = 'lclstorage_1';
lcl_images[0].value = 'http://www.superga.com/tcnimg/S/02/S009TE0/XBS009TE0___949______.jpg';
lcl_images[1] = new Object();
lcl_images[1].key = 'lclstorage_2';
lcl_images[1].value = 'https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/2150fb35419617.56f6327b44e47.gif';
for (var i = lcl_images.length - 1; i >= 0; i--) {
var valore = lcl_images[i].value;
localforage.setItem(lcl_images[i].key, lcl_images[i].value, function() {
console.log('Saved: ' + valore);
});
}
});
}
function use_preloaded_image() {
for (var i = lcl_images.length - 1; i >= 0; i--) {
var key = lcl_images[i].key;
localforage.getItem(lcl_images[i].key, function(err, readValue) {
console.log('Read: ', readValue);
document.getElementById(key).src = readValue;
});
}
}
关键是,我不知道使用图像的方法是否正确:我将它们存储为字符串,localForage应该使用parse
和stringify
。
这个例子工作正常(当我离线时,我刷新页面,本地存储中的图像是可见的),但我看到有人使用图像对象或 Blob(我从未听说过,并且即时搜索并没有告诉我太多相关信息)。
其他人发出 XHR 请求下载图像,然后保存它。
我可以考虑使用XHR请求来检查图片是否已经下载。这样对吗?
其次:有人说用blob存储更好。为什么?
请帮助我,谢谢。
编辑(多重承诺)
当我检索图像时,我必须将每个图像绑定到一个 <img>
。但我不知道该怎么做,有承诺。因为在使用 Promise.all()
时我不能使用 for
循环(所以没有索引将图像 src 与图像 id 绑定)。
var promises = [];
for (var i = lcl_images.length - 1; i >= 0; i--) {
promises.push(localforage.getItem(lcl_images[i].key));
}
Promise
.all(promises)
.then(function(value) {
console.log(value);
})
.catch(function(error) {
console.log(error);
});
for (var i = lcl_images.length - 1; i >= 0; i--) {
document.getElementById(lcl_images[i].key).src = value;
}
Promise
.all(promises)
.then(function(value) {
console.log(value);
document.getElementById(lcl_images[i].key).src = value;
// I can't get the index i, no way to set <img> src for id attribute
})
.catch(function(error) {
console.log(error);
});
FIX Promise.all().then()
Promise
.all(promises)
.then(function(value) {
console.log(value);
for (var i = lcl_images.length - 1; i >= 0; i--) {
document.getElementById(lcl_images[i].key).src = value[i];
};
})
Blob 更好,因为 IndexedDB 可以优化它们在磁盘上的存储。本质上,它将它们直接存储为文件句柄。 (在不支持 Blob 或不支持 IDB 的情况下,LocalForage 将转换为 base64。)
要将图像下载为 Blob,最简单的方法是使用获取 polyfill 或 fetch()
API 并使用 response.blob()
(参见 MDN docs)。另一种方法是使用 XMLHttpRequest 并执行 xhr.responseType = 'blob
。示例:
fetch('http://example.com/myimage.gif').then(function (response) {
return response.blob();
}).then(function (blob) {
console.log("yay I have a blob", blob);
}).catch(console.log.bind(console))
您还应该知道的另一件事是,您似乎在代码中犯了一个典型的 Promise 错误,即在 forEach()
循环中执行多个 Promise。您可能更愿意 Promise.all()
。请阅读 We have a problem with promises 了解更多详情。
要使用 Blob,您可以查看 blob-util, which has a tutorial, or you can read the PouchDB guide to attachments。 (PouchDB 使用与 LocalForage 类似的 Blob,因此建议类似。)