我正在构建一个“存储提供程序”,允许使用代码通过接口存储内容。考虑下面的代码片段是伪代码,因为我要去MCVE。我正试图抓住IMPORTANTDATA
和IMPORTANTKEY
下方。
在最低级别,我有baseService
:
define([], function(){
return function(){
this.sendRequest = function(data){
return $.ajax(data).done(function(response){
return response.IMPORTANTDATA; // <---- This is needed
}).fail(function(response){
throw new Error(response);
});
}
}
})
我使用它来构建服务以重用一些基本功能,例如 - eventService
:
define(["baseService"], function(baseService){
const eventService = new baseService();
eventService.postMediaEvent = function(eventType, mediaPath, storageProvider){
// isolated logic here
return eventService.sendRequest(someData);
}
})
这就是事情开始变得棘手的问题:我有一个baseStorageClient
:
define(["eventService"], function (eventService) {
return function(){
this.storageProvider = null;
const self = this;
this.storeMetadata = function(eventType, mediaPath){
return eventService.postMediaEvent(eventType, mediaPath, self.storageProvider);
};
this.storeMedia = function(){
throw new Error("Not Implemented");
};
}
}
但这个家伙并没有直接使用过。我创建了这个实例 - 例如indexedDbClient
:
define(["baseStorageClient"], function(baseStorageClient){
const indexedDbClient = new baseStorageClient();
indexedDbClient.storeMedia = function(blob){
return openDatabase().then(function () {
const request = database.transaction(storeName, "readwrite")
.objectStore(storeName)
.add(dbEntry);
request.onsuccess = function (event) {
logger.log("combined segments saved into database.");
// todo - figure out how to resolve here
return {
IMPORTANTKEY: dbEntry.mediaId // <---- This too
}
};
request.onerror = function (event) {
// todo: figure out how to reject here
logger.log("Unable to save segments " + e);
};
});
}
})
此客户端在我的storageInterface
中使用:
define(["indexedDbClient"], function(indexedDbClient){
const storageInterface = {};
var currentClient = indexedDbClient; // might be other clients
storageInterface.storeMedia = function (blob) {
return currentClient.storeMedia(blob).then(function(mediaPath) {
return currentClient.storeMetadata(eventType, mediaPath);
});
}
});
这是事情变得超级毛茸茸的地方。我想要实现的目标如下:
storageInterface.storeMedia(superBuffer).then(function (importantStuff) {
// this should go storeMedia > baseStorageClient > eventService
importantStuff.IMPORTANTKEY;
importantStuff.IMPORTANTDATA;
});
但我无法弄清楚如何处理这个问题。如何在这样的承诺链中编译结果?
答案 0 :(得分:1)
有两个主要问题:
您应该将done
和fail
视为已弃用。他们不允许任何链接,他们会放弃回调的结果。 始终使用then
。
sendRequest = function(data){
return $.ajax(data).then(function(response){
return response.IMPORTANTDATA;
}, function(response) {
throw new Error(response);
});
}
您的交易尚未返回任何承诺,因此您无需进行任何链接。您首先需要promisify:
function promiseFromRequest(req) {
return new Promise(function(resolve, reject) {
req.onsuccess = resolve;
req.onerror = reject;
});
}
现在你可以像这样使用它:
storeMedia = function(blob){
return openDatabase().then(function () {
return promiseFromRequest(database.transaction(storeName, "readwrite")
.objectStore(storeName)
.add(dbEntry))
.then(function (event) {
logger.log("combined segments saved into database.");
return {
IMPORTANTKEY: dbEntry.mediaId
}
}, function (e) {
logger.log("Unable to save segments " + e);
throw e;
};
});
};
有了这些,您应该可以storeMedia
和storeMetaData
以某种方式combine结果。