2015-10-29 2 views
0

У меня есть метод, который выполняет асинхронный запрос ajax для получения информации о разрешении с сервера (SharePoint) для кэширования через JS, чтобы я мог получить к нему доступ для CSR. Иногда это занимает немного больше времени (500 мс) ... не всегда, но иногда остальная часть скрипта загружается так быстро, что ему требуется разрешение до того, как запрос ajax полностью завершен.Javascript: метод синхронного ожидания/задержки

Есть ли простой способ просто отсрочить вывод метода? Я пробовал разные вещи с помощью SetTimeout(), но ничего не получилось.

Вот simplyfied код ...

var Permissions = { 
    get: function(key) { 
     while (this.cacheLoaded != true) { 
      wait(100); //<-- This is what I need 
     } 
     return (typeof this[key] != 'undefined' && this[key] == true) ? true : false;  
    }, 
    cacheLoaded: false, 
    buildCache: function() { 
     // load permissions asynchronously by ajax 
     . 
     . 
     . 
     Permissions.cacheLoaded = true; 
    } 
} 
Permissions.buildCache(); 
. 
. 
. 
doLotsOfOtherStuff(); 
. 
. 
.  
//Here is the actual call of the get-function: 
if (Permission.get('ALOW_DELETE')) { 
    deleteSomething(); 
} 

Конечно, я мог бы переключить requst Ajax синхронными. Но это задержит загрузку всего скрипта. Поэтому на самом деле я хочу задержать jsut getter в течение нескольких миллисекунд, пока запрос не будет завершен.

+4

У вас нет необходимости делать запрос синхронным, но вы действительно не можете надежно делать что-либо еще до тех пор, пока исходный запрос не будет завершен. Все «doLotsOfOtherStuff» и т. Д. Должны выполняться после загрузки кеша - в обратном вызове ajax. –

+0

Вы не можете 'wait' [пока] (https://jakearchibald.com/2014/es7-async-functions/) - вам нужно поставить логику, которая нуждается в данных внутри обратного вызова (или обработчика Promise) для Запрос AJAX. – joews

+0

Вы видели [это] (http://stackoverflow.com/questions/3709597/wait-until-all-jquery-ajax-requests-are-done)? –

ответ

-1

Я пропущу часть об этом, представляя собой очень плохую практику и всегда использую таймауты и обратные вызовы.

Поскольку js однопоточный, у вас не так много вариантов. Я бы пошел с пустым циклом, но, как сообщает @joews, это остановит выполнение, а cacheLoaded никогда не будет установлено в true;

while (this.cacheLoaded != true) { /*Stall*/ } 

EDIT:

Обратный вызов Решение:

get: function(key, callback) { 
     var fn = function { 
      if(this.cacheLoaded != true) 
       window.setTimeout(fn, 500); 
      else 
       callback((typeof this[key] != 'undefined' && this[key] == true) ? true : false); 
     }; 
     fn();  
    } 

Затем вызовите его следующим образом:

Permission.get('ALOW_DELETE', function(result) {if(result) deleteSomething();}); 
+1

Это не сработает, потому что выполнение JS останется в текущем стеке вызовов. 'cacheLoaded' может быть установлен в true только для более позднего тика цикла событий, к которому JS-движок никогда не получит. – joews

+0

@joews Ты прав. Я отметил это и добавил фактическое решение. – Dan

0

Существует в init.js_spYield(a,b) который объявлен как:

function _spYield(b, a) { 
if (a > 0) 
    window.setTimeout(function() { 
     _spYield(b, a - 1) 
    } 
    , 0); 
else 
    b() 

Смежные вопросы