Javascript JS中处理回调的策略

Javascript JS中处理回调的策略,javascript,Javascript,这是一个noob JS问题,我无法很好地用语言表达,以成功地使用Google function getUser(username){ var toReturn = { }; Restangular.one('users', username).get().then(function(result){ toReturn = result; }); return toReturn //doesn't work } restangla

这是一个noob JS问题,我无法很好地用语言表达,以成功地使用Google

function getUser(username){
    var toReturn = { };
    Restangular.one('users', username).get().then(function(result){ 
        toReturn = result;   
    });        
return toReturn //doesn't work 
}
restanglar.one(…).get()
初始化REST调用以从服务器获取用户数据<代码>。然后(…)是返回数据后运行的回调。但是,这个
getUser()
函数在编写时总是返回一个空对象,因为它在触发回调之前返回。如何编写此函数,使其返回检索到的对象


(顺便说一句,我知道这个问题是关于角度的学术性问题,因为它透明地处理承诺决议。我对JS一般来说是新手,这是一个一般JS问题)

因为服务器调用是异步的,所以应该提供回调

您可以使用
promise
callback

使用回调

 function getUser(username, callback){

    Restangular.one('users', username).get().then(function(result){ 
        callback(result);   
    });        
 }
调用:
getUser('username',函数(result){/*do stuff here*/})

使用承诺

 function getUser(username){
    var callback;
    var promise = {then: function(cb){
         callback = cb;
      }
    };
    Restangular.one('users', username).get().then(function(result){ 
        callback(result);   
    }); 
   return promise;       
 }
调用:
getUser('username')。然后(函数(结果){/*dostuff here*/});)

只需尝试:

function getUser(username, callback){
    Restangular.one('users', username).get().then(callback);
}

getUser('hsz', function(result){ 
    console.log(result); 
});

rest调用可能是一个异步调用。如果您可以控制API,则可以发出同步请求,然后等待它返回。大概是这样的:

function getUser(username){
    var toReturn = { };
    return Restangular.one('users', username).get().then(function(result){ 
        return result;   
    });
}
getUser('Daniel', function(user) { updateSomethingWithMyUser(user); });
这也取决于如何处理。我在这里假设then()也将返回结果

但是,此scneario中的最佳方式是使用回调:

function getUser(username, callback) {
    Restangular.one('users', username).get().then(callback);
}

是的,那不行,因为问题出在你的功能上。每个AJAX调用都是异步执行的,因此与结果类似

如果您进行了这样的AJAX调用,那么它必须要求浏览器加载该请求,处理响应,然后执行(function(result){}),将其作为结果的最后一个参数

因此,您必须更改函数以使其也具有回调,如:

function getUser(username, onResultHandler){
    Restangular.one('users', username).get().then(onResultHandler);        
}
然后你可以这样使用它:

function getUser(username){
    var toReturn = { };
    return Restangular.one('users', username).get().then(function(result){ 
        return result;   
    });
}
getUser('Daniel', function(user) { updateSomethingWithMyUser(user); });

明白了吗?

最简单的方法是不要覆盖刚刚创建的对象,因为对象是通过引用传递的

例如:

var a = function() { 
     var b = {}; 
     setTimeout(function() { b.a = 'hi'; }, 100); 
     return b; 
}

b = a();
console.log(b); // Object {}
setTimeout(function() { console.log(b) }, 100); // Object {a: "hi"}
因为我们只是设置了对象的一个属性,所以我们在返回的同一个对象上设置了一个属性。当您执行以下操作时:

toReturn = result;   
就像在函数中一样,您不是在更改toReturn引用的对象,而是在更改toReturn引用的对象(它以前引用{},现在它引用它所引用的任何结果)

因此,在你的情况下:

function getUser(username){
  var toReturn = { };
  Restangular.one('users', username).get().then(function(result){ 
    toReturn.result = result;   
  });        
  return toReturn;
}
一旦得到结果,
toReturn.result
就会得到它

如何编写此函数,使其返回检索到的对象

你不能,也不应该。Restangular使调用异步,以便应用程序可以在等待响应时继续运行

如果您想让它看起来是同步的,我建议使用以下方法(这里是它与其他答案不同的地方):


回调函数是异步调用的吗?看看如何处理没有承诺的异步函数