JS中处理回调的策略

Strategies for handling callbacks in JS

本文关键字:策略 回调 处理 JS      更新时间:2023-09-26

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

function getUser(username){
    var toReturn = { };
    Restangular.one('users', username).get().then(function(result){ 
        toReturn = result;   
    });        
return toReturn //doesn't work 
}

Restangular.one(...).get()初始化REST调用以从服务器获取用户数据。.then(...)是在返回数据后运行的回调。但是,这个getUser()函数在编写时总是返回一个空对象,因为它在触发回调之前返回。如何编写此函数,使其返回检索到的对象?

(附言:我知道这个问题是关于angular的学术性问题,因为它透明地处理promise解析。一般来说,我是JS的新手,这是一个普通的JS问题)。

由于服务器调用是异步的,因此应该提供回调。

您可以使用promisecallback

使用回调

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

调用:getUser('username', function(result){ /*do stuff here */ });

使用Promise

 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').then(function(result){ /*do stuff 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;   
    });
}

这也取决于如何处理。我在这里假设then()也会返回结果。

然而,在这个scneario中最好的方法是使用回调:

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

是的,这不起作用,因为问题出在您的函数上。每个AJAX调用都是异步执行的,因此与结果类似。

如果你进行了这样的AJAX调用,它将不得不要求浏览器加载该请求,处理响应,然后执行(函数(结果){}),将其作为结果的最后一个参数。

所以,你必须改变你的函数,也有一个回调,比如:

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

然后你可以这样使用它:

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"}

因为我们只是设置了对象的一个属性,所以我们在返回的SAME对象上设置了一个属性。当你做这样的事情时:

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使调用异步,这样您的应用程序就可以在等待响应的同时继续运行。

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

function getUser(username){
    return Restangular.one('users', username).get();
}
/* Usage */
getUser('username')
.then(function(result) {
    /* do something with result */ 
});