Ila*_*Ila 2 javascript asynchronous angularjs
我正在使用AngularJS + SQLite数据库构建PhoneGap应用程序.我有一个经典的"异步工作如何"与数据库查询的角度问题,得到错误"无法调用方法然后未定义".我希望有人可以帮助我看到我的方式的错误.
这是我的查询功能.此处的每个alert()都返回有意义的数据,表明事务本身是成功的:
.factory('SQLService', ['$q', '$rootScope', 'phonegapReady',
function ($q, $rootScope, phonegapReady) {
function search(query) {
alert("Search running with " + query);
var promise = db.transaction(function(transaction) {
var str = "SELECT category, id, chapter, header, snippet(guidelines, '<b>', '</b>', '...', '-1', '-24' ) AS snip FROM guidelines WHERE content MATCH '" + query + "*';";
transaction.executeSql(str,[], function(transaction, result) {
var resultObj = {},
responses = [];
if (result != null && result.rows != null) {
for (var i = 0; i < result.rows.length; i++) {
resultObj = result.rows.item(i);
alert(resultObj.category); //gives a meaningful value from the DB
responses.push(resultObj);
}
} else {
//default content
}
},defaultNullHandler,defaultErrorHandler);
alert("End of transaction");
});
// Attempting to return the promise to the controller
alert("Return promise"); //this alert happens
return promise;
}
return {
openDB : openDB,
search: search
};
}]);
Run Code Online (Sandbox Code Playgroud)
在我的控制器中,它给出了"无法调用方法然后未定义"错误:
$scope.search = function(query) {
SQLService.search(query).then(function(d) {
console.log("Search THEN"); //never runs
$scope.responses = d; //is never defined
});
}
Run Code Online (Sandbox Code Playgroud)
感谢接受的答案,这是完整的工作代码.
function search(query) {
var deferred = $q.defer();
db.transaction(function(transaction) {
var str = "SELECT category, id, chapter, header, snippet(guidelines, '<b>', '</b>', '...', '-1', '-24' ) AS snip FROM guidelines WHERE content MATCH '" + query + "*';";
transaction.executeSql(str,[], function(transaction, result) {
var resultObj = {},
responses = [];
if (result != null && result.rows != null) {
for (var i = 0; i < result.rows.length; i++) {
resultObj = result.rows.item(i);
responses.push(resultObj);
}
} else {
resultObj.snip = "No results for " + query;
responses.push(resultObj)
}
deferred.resolve(responses); //at the end of processing the responses
},defaultNullHandler,defaultErrorHandler);
});
// Return the promise to the controller
return deferred.promise;
}
Run Code Online (Sandbox Code Playgroud)
$scope.search = function(query) {
SQLService.search(query).then(function(d) {
$scope.responses = d;
});
}
Run Code Online (Sandbox Code Playgroud)
然后,我可以使用$ scope.responses访问模板中的响应.
这里的问题是:什么db.transaction回归.
从您使用它的方式来看,我猜测它是一些不会返回承诺的第三方代码.
假设您正确使用它(alert显示正确的结果),您需要实际使用$q以使承诺有效.
像这样的东西:
function search(query) {
// Set up the $q deferred object.
var deferred = $q.defer();
db.transaction(function(transaction) {
transaction.executeSql(str, [], function(transaction, result) {
// do whatever you need to do to the result
var results = parseDataFrom(result);
// resolve the promise with the results
deferred.resolve(results);
}, nullHandler, errorHandler);
});
// Return the deferred's promise.
return deferred.promise;
}
Run Code Online (Sandbox Code Playgroud)
现在,在您的控制器中,该SQLService.search方法将返回一个承诺,该承诺应该通过您的数据库调用结果得到解决.