AngularJs:当内部调用$ http或$ resource时,让方法同步返回

Jef*_*ing 20 javascript angularjs

有没有办法等待一个承诺,以便你可以从中获得实际结果并返回而不是返回承诺本身?我正在考虑类似于C#await关键字如何与Tasks一起工作的东西.

下面是一个示例,说明为什么我希望像canAccess()这样的方法返回true或false而不是promise,以便可以在if语句中使用它.方法canAccess()将使用$ http或$ resource进行AJAX调用,然后以某种方式等待promise得到解决.

看起来像这样:

$scope.canAccess = function(page) {
    var resource = $resource('/api/access/:page');
    var result = resource.get({page: page});

    // how to await this and not return the promise but the real value
    return result.canAccess;
}
Run Code Online (Sandbox Code Playgroud)

反正有没有这样做?

谢谢.

Joh*_*sch 25

一般来说,这是个坏主意.让我来告诉你为什么.浏览器中的JavaScript基本上是单线程的野兽.想想看,它也是Node.js中的单线程.因此,在您开始等待远程请求成功或失败时,您所做的任何事情都不会"返回",这可能会涉及某种循环,以延迟请求后代码的执行.像这样的东西:

var semaphore = false;
var superImportantInfo = null;

// Make a remote request.
$http.get('some wonderful URL for a service').then(function (results) {
  superImportantInfo = results;

  semaphore = true;
});

while (!semaphore) {
  // We're just waiting.
}

// Code we're trying to avoid running until we know the results of the URL call.
console.log('The thing I want for lunch is... " + superImportantInfo);
Run Code Online (Sandbox Code Playgroud)

但是如果你在浏览器中尝试并且调用需要很长时间,浏览器会认为你的JavaScript代码陷入循环并在用户面部弹出一条消息,让用户有机会停止你的代码.因此JavaScript构造如下:

// Make a remote request.
$http.get('some wonderful URL for a service').then(function (results) {
  // Code we're trying to avoid running until we know the results of the URL call.
  console.log('The thing I want for lunch is... " + results);
});

// Continue on with other code which does not need the super important info or 
// simply end our JavaScript altogether. The code inside the callback will be 
// executed later.
Run Code Online (Sandbox Code Playgroud)

这个想法是每当服务调用返回时,回调中的代码将由事件触发.因为事件驱动是JavaScript喜欢它的方式.JavaScript中的计时器是事件,用户操作是事件,发送和接收数据的HTTP/HTTPS调用也生成事件.并且您需要构建代码以在它们到来时响应这些事件.

您是否可以构造您的代码,使得它认为canAccess是错误的,直到远程服务调用返回并且它可能发现它确实是真的?我一直在AngularJS代码中这样做,我不知道我应该向用户显示的最终权限集是因为我还没有收到它们或者我还没有收到要显示的所有数据首先是页面.我有默认值显示,直到真实数据返回,然后页面根据新数据调整为新的形式.AngularJS的双向绑定使得这非常容易.

  • 在某些情况下,你真的想等,我认为那是原来的问题.这个答案并没有真正回答这个问题. (6认同)
  • 在第一个例子中,我不认为`while`语句的条件永远不会真实.这是因为它将同步运行并阻止HTTP请求发生. (5认同)
  • 即使我同意答案中提出的观点,我也不喜欢"你甚至不应该这样做,做别的事情"的答案,因为他们没有回答这个问题.回答问题! (3认同)