我正在尝试使用 Javascript 的最佳实践,但这对我来说太难了。在这种情况下,我想使用一些函数来“避免”回调。我正在尝试使用 jquery 的 Deferred 对象来完成它。所以我相信我不知道如何工作。
我正在使用 phonegap + emberjs + cordova-sqlite-plugin。
我有以下实现回调的函数。
getPuntos: function(callback)
{
var db = window.sqlitePlugin.openDatabase("Rondas", "1.0", "Dev", -1);
var ret ={data:false};
db.transaction(function(tx)
{
tx.executeSql("SELECT * from Punto;",[], function(tx, res)
{
if( res.rows.length !== 0)
{
var puntos = [];
for( var i=0; i<res.rows.length; i++)
{
var descripcion = res.rows.item(i).descripcion;
var id = res.rows.item(i).id;
//console.log( descripcion );
var punto = App.Punto.create( { index: i, id:id, descripcion: descripcion});
puntos.push( punto );
}
ret.data = puntos;
callback(ret.data);
}
});
},function(tx,err){
console.log('Error SQL'+err);
},function(){
console.log( 'Base de datos abierta' );
});
}
我也用这个:
this.getPuntos(function(puntos){
for( var i=0; i<puntos.length; i++){
console.log( puntos[i] );
}
});
好吧,但我尝试实现一些非常清晰和简单的东西,比如:
//whitout use a callback.
var puntos = this.getPuntos();
for( var i=0; i<puntos.length; i++){
console.log( puntos[i] );
}
然后我尝试这样做:
- 将函数
getPuntos
更改为_getPuntos
,此函数有一个延迟对象。 getPuntos
函数是一个包装器,用于处理_getPuntos
方法中 promise 的结果并尝试返回。(但不起作用)
_getPuntos: function()
{
var db = window.sqlitePlugin.openDatabase("Rondas", "1.0", "Dev", -1);
var deferred = jQuery.Deferred();
var ret ={data:false};
db.transaction(function(tx)
{
tx.executeSql("SELECT * from Punto;",[], function(tx, res)
{
if( res.rows.length !== 0)
{
var puntos = [];
for( var i=0; i<res.rows.length; i++)
{
var descripcion = res.rows.item(i).descripcion;
var id = res.rows.item(i).id;
//console.log( descripcion );
var punto = App.Punto.create( { index: i, id:id, descripcion: descripcion});
puntos.push( punto );
}
//ret.data = puntos;
//callback(ret.data);
deferred.resolve(puntos);
}
});
},function(tx,err){
console.log('Error SQL'+err);
},function(){
console.log( 'Base de datos abierta' );
});
return deferred.promise();
},
包装器:
getPuntos: function()
{
var promise = this._getPuntos();
var ret = {data:false};
promise.done(function(result)
{
ret.data = result;
return ret.data;
});
while(ret.data ===false ){} //wait for the result until it's available
return ret.data;
},
在主函数中我调用它:
var puntos = this.getPuntos();
console.log( puntos+"--shoulbe [object]"); //I get Undefined or false, but no my array.
所以,有什么办法可以做到这一点,将异步函数转换为同步函数 功能?
感谢您的所有回答。
最佳答案
这里的主要问题是第二个示例中的 getPuntos() 函数不返回任何内容,因此返回 null/false 值。
getPuntos: function()
{
var promise = this._getPuntos();
var ret = {data:false};
promise.done(function(result)
{
// This happens in the future
ret.data = result;
return ret.data;
});
// This happens now and there is nothing returned
},
当您的 promise 完成时 (promise.done),它会返回 ret.data 但这会返回到 promise 并被忽略。它在错误的范围内。你在传统的“拉”模型中思考,数据被拉向你,程序阻塞直到数据可用。 Javascript 使用回调,更像是一种“推送”模型,其中数据在可用且没有阻塞时被推送到回调。
你需要重新安排事情。例如,getPuntos 函数应返回 promise 。
getPuntos: function()
{
var promise = this._getPuntos();
return promise;
},
并且 main 函数应该在 promise 完成时添加一个回调。
var puntos = this.getPuntos();
puntos.done(function(result) {
console.log( result+"--shoulbe [object]");
});
虽然 getPuntos() 函数在这里有点多余,因为它只是返回 _getPuntos() 的值。
关于javascript - 使用 Pattern promise jquery 将异步函数更改为同步函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24985933/