2013-08-30 22 views
0

試圖解決一個控制器內部在以下情況推遲AngularJS:Q deferreds和requestFileSystem

services.factory('MyService', ['$q', 
function($q) { 
    var Foo = function() { 
    var deferred = $q.defer(); 
    window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; 
    window.requestFileSystem(window.TEMPORARY, 1024 * 1024, deferred.resolve, this.errorHandler); 
    return deferred.promise; 
    } 

    return { 
    Foo: Foo 
    } 
} 
]); 

然後,當我遇到一些問題:

var bar = new MyService.Foo().then(function(cb) { 
    console.log(cb) 
}); 

如果我使用deferred.resolve外部requestFileSystem函數,然後它完美的工作,但在上面的情況沒有任何反應。 PS:requestFileSystem函數的第三個參數是一個回調函數,它在準備好文件系統對象後就會獲取它。

編輯: 這是條:

Object {then: function, catch: function, finally: function} 

的第四個參數requestFileSystem是登錄到控制檯文件系統API初始化錯誤,但在這種情況下,它不叫功能,因爲requestFileSystem成功如此deferred.resolve應叫做。如果我更換一個正常功能延遲:

window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function(filesystem){ 
    console.log(filesystem); 
}, this.errorHandler); 

然後文件系統對象返回正確:

DOMFileSystem {root: DirectoryEntry, name: "http_127.0.0.1_3000:Temporary"} 

EDIT2:

我試圖用我自己的模擬requestFilesystem功能做一個簡單的測試功能和它的工作原理:

var Foo = function() { 
    var deferred = $q.defer(); 
    asd(deferred.resolve) 
    return deferred.promise; 
} 

function asd(callback) { 
    callback('it works') 
} 

MyService.Foo().then(function(cb){ 
    console.log(cb) 
}) 
+0

我猜承諾一個更好的解決方案被退回,但它從來沒有得到解決?添加一些調試語句以查看它掛起的位置。 – Halcyon

+0

第四個參數是什麼?你在控制檯中是否有任何錯誤?不要使用'new','Foo'不是構造函數。 – Bergi

+0

你能指點一下'requestFileSystem'方法嗎? – Chandermani

回答

1

基本問題是如何以及何時調用。
固定碼:

services.factory('MyService', ['$q','$rootScope', 
function($q,$rootScope) { 
    var Foo = function() { 
    var deferred = $q.defer(); 
    window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; 
    window.requestFileSystem(window.TEMPORARY, 1024 * 1024, function(result){ 
     deferred.resolve(result); 
     $rootScope.$apply();//force angular to resolve promise 
    }, this.errorHandler); 
    return deferred.promise; 
    } 

    return { 
    Foo: Foo 
    } 
} 
]); 

事情是,當你調用「deferred.resolve」角生命週期的外部(文件系統請求的回調是角生命週期的外部),必須手動調用「$ $ rootScope申請。 ()',否則承諾不會解決。

+0

您可以通過圍繞'resolve'函數,它是一個閉包,它不依賴於調用正確的延遲對象。我在源代碼中檢查過它,因爲這是我的第一個懷疑:-) – Bergi

+0

@Bergi哎呀,我的壞,謝謝。就在幾個小時前,我看到像deferred [fnc] .apply(deferred,params)這樣的調用,所以我認爲它是依賴的。 – jusio

1

有來自github.com/maciel310/angular-filesystem

//wrap resolve/reject in an empty $timeout so it happens within the Angular call stack 
//easier than .apply() since no scope is needed and doesn't error if already within an apply 
function safeResolve(deferral, message) { 
    $timeout(function() { 
     deferral.resolve(message); 
    }); 
} 
function safeReject(deferral, message) { 
    $timeout(function() { 
     deferral.reject(message); 
    }); 
} 
相關問題