通过一系列promise(JS继承/接口)编译结果

时间:2017-05-31 23:21:29

标签: javascript jquery ajax promise

我正在构建一个“存储提供程序”,允许使用代码通过接口存储内容。考虑下面的代码片段是伪代码,因为我要去MCVE。我正试图抓住IMPORTANTDATAIMPORTANTKEY下方。

在最低级别,我有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;         
 });

但我无法弄清楚如何处理这个问题。如何在这样的承诺链中编译结果?

1 个答案:

答案 0 :(得分:1)

有两个主要问题:

  • 您应该将donefail视为已弃用。他们不允许任何链接,他们会放弃回调的结果。 始终使用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;
            };
        });
    };
    

有了这些,您应该可以storeMediastoreMetaData以某种方式combine结果。