使用自定义方法扩展 $.Deferred.pipe()?

Posted

技术标签:

【中文标题】使用自定义方法扩展 $.Deferred.pipe()?【英文标题】:Extend $.Deferred.pipe() with a custom method? 【发布时间】:2012-09-10 02:42:45 【问题描述】:

我想用自定义方法扩展 $.Deferred.pipe,这样我就可以稍微缩短我的延迟链。

我目前的代码是这样的

getDeferredFileEntry() 
//returns a ($.Deferred) promise to resolve with a FileEntry object
    .pipe(function(entry)
        //returns a promise to resolve with an object
        //containing the contents of the file as text
        //and a reference to the file's FileEntry
        var def = $.Deferred();
        entry.getDeferredText()
            .done(function(fileText)
                def.resolve(text:fileText, fileEntry:entry);
            );
        return def.promise();
    )
    .done(function(response)
        var text = response.text;
        var fileEntry = response.fileEntry;

        console.log(text);
        //do something with the text
        console.log(fileEntry);
        //do something else with the file entry after finished reading from it
        //e.g. deleting with something like fileEntry.remove();
    );

我想把它缩短为

getDeferredFileEntry()
    .read(
        //uses the FileEntry object resolved by getDeferredFileEntry
        //to call an asynchronous fileEntry.read() *in the background*
        //the contents are then passed to the callback taken from below
        //returns promise to resolve with the fileEntry object for chaining
        function callback(text) 
            //do something with the text
            console.log(text);
        
    ) 
    .remove(
        function(fileEntry)
            //library call to remove fileEntry that read() promised
        
    )

我正在努力解决如何将 FileEntry 对象从 getDeferredFileEntry() 解析到后台的自定义 read()。任何建议将不胜感激

【问题讨论】:

getDeferredFileEntry 是如何定义的?它返回的 promise 对象需要修改以添加额外的 read 方法,或者您必须将新的 read 方法添加到所有 promise 对象。 【参考方案1】:

为什么不简单地创建一些帮助方法来抽象出你的管道逻辑?

function getFileEntry() 
   // Returns a promise resolved when your file entry is available


function getFileContents( entryPromise ) 
  return entryPromise.pipe(function( entry ) 
    return readFileEntry( entry );
  );


function readFileEntry( entry ) 
  var dfr = $.Deferred();

  // do whatever you have to do to read the file
  // then call dfr.resolve( fileContents );

  return dfr.promise();


function removeFileEntry( entry ) 
  var dfr = $.Deferred();

  // do whatever you have to do to remove the file
  // then call dfr.resolve();

  return dfr.promise();

使用这些方法,您的代码最终应该如下所示:

var fileEntry = getFileEntry();

readFileEntry( fileEntry ).then(function(contents) 
    // Do something with your file contents
    removeFileEntry( fileEntry );
);

【讨论】:

【参考方案2】:

我认为自定义方法不会有太大帮助,您仍然需要尊重链接(例如,通过维护内部队列)。

在您的情况下,嵌套回调是最简单的事情:

getDeferredFileEntry().then(function(entry) 
    return entry.getDeferredText().then(function(text) 
    // after finished reading from it:
        console.log(txt); // do something with the read text
        console.log(fileEntry); // do something with the file entry
        return fileEntry.remove(); // e.g. deleting it
    );
);

如果您更想使用管道解决方案,可以将其简化为

.pipe(function(entry) 
    return entry.getDeferredText().pipe(function(fileText) 
        return text:fileText, fileEntry:entry;
    );
)

...而不是手动构建 Deferreds。

【讨论】:

以上是关于使用自定义方法扩展 $.Deferred.pipe()?的主要内容,如果未能解决你的问题,请参考以下文章

C# - 在自定义控制台扩展方法中使用常规 Console.WriteLine 格式?

编辑器扩展基础3-自定义PropertyDrawer

自定义类扩展 Array 而不使用扩展语法

Jquery自定义扩展方法

C#获取自定义属性扩展方法

Jquery自定义扩展方法--HTML日历控件