Вы можете использовать общий (общий) метод для чтения атрибута над данным MemberInfo
public static bool TryGetAttribute<T>(MemberInfo memberInfo, out T customAttribute) where T: Attribute {
var attributes = memberInfo.GetCustomAttributes(typeof(T), false).FirstOrDefault();
if (attributes == null) {
customAttribute = null;
return false;
}
customAttribute = (T)attributes;
return true;
}
С 2009 года, когда был задан этот вопрос, JavaScript значительно эволюционировал. Все остальные ответы сейчас устарели или слишком сложны. Вот текущая лучшая практика:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function demo() {
console.log('Taking a break...');
await sleep(2000);
console.log('Two seconds later, showing sleep in a loop...');
// Sleep in loop
for (let i = 0; i < 5; i++) {
if (i === 3)
await sleep(2000);
console.log(i);
}
}
demo();
await sleep(<duration>)
. [+1129] Обратите внимание, что
await
может выполняться только в функциях с префиксом с ключевым словом async
или на верхнем уровне вашего сценария в некоторых средах ( например, консоль Chrome DevTools или Runkit). await
только приостанавливает текущую функцию async
Две новые функции JavaScript помогли написать эту функцию «сна»:
async/await
позволяет коду явно ожидать обещание выполнить (разрешить или отклонить). async
/ await
приземлился в V8 и был включен по умолчанию после Chrome 55 (выпущен в декабре 2016 года) Если по какой-то странной причине вы используете Node старше чем 7 (который достиг конца срока службы ) или нацелены на старые браузеры, async
/ await
все еще можно использовать через Babel (инструмент, который будет переносить JavaScript + новые функции в простой старый JavaScript), с плагином transform-async-to-generator
.
Я использую многопоточный HTML5 Worker, который сможет прервать синхронный запрос XMLHttpRequest, указывающий на не отвечающий URL. Это не блокирует браузер.
Существует новая библиотека, которая аккуратно объединяет функции вместе с таймаутами, чтобы вы могли избежать ада обратного вызова.
Превращает это:
setTimeout(function(timeout){
function1();
setTimeout(function(timeout){
function2();
setTimeout(function(timeout){
function3();
}, timeout, timeout)
}, timeout, timeout)
}, 10, 10);
в это:
Sequencr.chain([function1, function2, function3], 10);
И имеет встроенную поддержку для петель что "спит" между каждой итерации.
Вы можете использовать закрывающий вызов setTimeout () с постепенно увеличивающимися значениями.
var items = ['item1', 'item2', 'item3'];
function functionToExecute(item) {
console.log('function executed for item: ' + item);
}
$.each(items, function (index, item) {
var timeoutValue = index * 2000;
setTimeout(function() {
console.log('waited ' + timeoutValue + ' milliseconds');
functionToExecute(item);
}, timeoutValue);
});
Результат:
waited 0 milliseconds
function executed for item: item1
waited 2000 milliseconds
function executed for item: item2
waited 4000 milliseconds
function executed for item: item3
Если вы хотите перевести анонимную функцию, например, созданную вами в качестве обработчика, я рекомендую следующее:
function()
{
if (!wait_condition)
{
setTimeout(arguments.callee, 100, /*comma-separated arguments here*/);
}
//rest of function
}
Этот код говорит: «Если условие ожидания еще не выполнено, вызовите эта функция снова с этими аргументами. " Я использовал этот метод для передачи одних и тех же аргументов моим обработчикам, что фактически делает этот код незапрашивающим sleep () (который работает только в начале вашей функции).
var waitTillSomethingHappens = function(){
if(somethingHappened == 1)
{
alert('Something Happened get out of sleep');
}
else
{
setTimeout(waitTillSomethingHappens,1000);
}
};
await new Promise(resolve => setTimeout(resolve, 2000));
убедитесь, что ваша вызывающая функция асинхронная
проверена и работает нормально
В Livescript (который компилируется в Javascript) вы можете сделать следующее:
sleep = (ms, func) -> set-timeout func, ms
console.log "hello-1"
<- sleep 2000ms
console.log "hello-2"
<- sleep 2000ms
console.log "hello-3"
Функции JavaScript не допускают приостановки. С синхронными Javascript-процедурами реализованы. Процедуры ожидают операций ввода-вывода и времени ожидания. Доступно для JavaScript 1.7.
Я предпочитаю эту функциональную функцию sleep
:
const sleep = ms =>
Promise(resolve => setTimeout(resolve, ms))
Это поможет вам.
var reloadAfter = 10; //seconds
var intervalId = setTimeout(function() {
//code you want to execute after the time waiting
}, reloadAfter * 1000); // 60000 = 60 sec = 1 min
Проблема большинства решений заключается в том, что они перематывают стек. В некоторых случаях это может быть большой проблемой. В этом примере я показываю, как по-разному использовать итераторы для имитации реального сна
. В этом примере генератор называть его собственным next()
, поэтому, как только он уйдет, он сам по себе.
var h=a();
h.next().value.r=h; //that's how U run it, best I came up with
//sleep without breaking stack !!!
function *a(){
var obj= {};
console.log("going to sleep....2s")
setTimeout(function(){obj.r.next();},2000)
yield obj;
console.log("woke up");
console.log("going to sleep no 2....2s")
setTimeout(function(){obj.r.next();},2000)
yield obj;
console.log("woke up");
console.log("going to sleep no 3....2s")
setTimeout(function(){obj.r.next();},2000)
yield obj;
console.log("done");
}
Теперь также возможно использовать собственный модуль util для обещания регулярных функций синхронизации.
const { promisify } = require('util')
const sleep = promisify(setTimeout)
module.exports = () => {
await someAsyncFunction()
await sleep(2000)
console.log('2 seconds later...')
}
Другой возможный способ:
var _timer;
clearTimeout(_timer);
_timer = setTimeout(function() {
// Your code
}, 1000); // Delay for 1 s.
Проблема с использованием реальной функции сна состоит в том, что JavaScript является однопоточным, и функция сна в значительной степени заставит ваш браузер зависать в течение этого времени.
Я получил Promise - не конструктор, использующий верхний ответ. Если вы импортируете Bluebird, вы можете сделать это. Простейшее решение ИМО.
import * as Promise from 'bluebird';
await Promise.delay(5000)
Это может быть немного поздно, немного лениво, немного скучно, немного навязчиво или немного похоже на «спину, большой рот», но ...
Каждое решение, которое я до сих пор читал, было бы похоже на «давай спать и посмотрим, что случилось завтра».
setInterval (обратный вызов, время) будет долго ждать, а затем обратный вызов, в то время как блокировка времени выполнения. Текущая реализация "setInterval" далека от сохранения потока, даже не говоря уже о параллелизме.
Хотя упомянутые разреженные решения выглядят как, угадайте, что C # ( смеется ), они все еще не работают, как в C # / .NET. Они все еще работают как в C.
В настоящее время JavaScript НЕ предоставляет архитектуру для реализации реальной многопоточности. Лучшим подходом был бы TypeScript, но все же в нем так мало реального решения, что ... больно. JavaScript, JQuery, AJAX, JNode и даже TypeScript - это всего лишь группа Wannabes, полагающихся на благо и плохое настроение разработчиков. Факт. Полная остановка.
Если вы действительно хотите приостановить выполнение сценария, вы можете сделать это:
var milliseconds;
var pretime;
var stage;
function step(time){
switch(stage){
case 0:
//Code before the pause
pretime=time;
milliseconds=XXX;
stage=1;
break;
case 1:
//Code that is looped through while paused
if(time-pretime >= milliseconds){
//Code after the pause
pretime=time;
milliseconds=XXX;
stage=2;
}
break;
case 2:
//Code that is looped through while paused
if(time-pretime >= milliseconds){
//Code after the pause
pretime=time;
milliseconds=XXX;
stage=3;
}
break;
case 3:
//Etc...
}
Window.requestAnimationFrame(step)
}
step();
Это, вероятно, именно то, что вы хотите, если вы все равно используете цикл, и вы можете изменить это таким образом, чтобы у вас была псевдо-многопоточность, когда некоторые функции ожидают некоторое время, а другие работают нормально. Я использую это все время для игр с чистым JS.
Подводя итог (как было сказано в предыдущих ответах):
В JavaScript нет встроенной функции сна. Вы должны использовать setTimeout или setInterval для достижения аналогичного эффекта.
Если бы вы действительно хотели, вы могли бы смоделировать режим сна с помощью цикла for, подобного показанному в исходном вопросе, но это сделало бы ваш процессор сумасшедшим. Внутри Web Worker альтернативным решением было бы сделать синхронный XMLHttpRequest
с неотвечающим IP и установить правильный таймаут. Это позволит избежать проблемы использования процессора. Вот пример кода:
// Works only inside a web worker
function sleep(milliseconds) {
var req = new XMLHttpRequest();
req.open("GET", "http://192.0.2.0/", false);
req.timeout = milliseconds;
try {
req.send();
} catch (ex) {
}
}
console.log('Sleeping for 1 second...');
sleep(1000);
console.log('Slept!');
console.log('Sleeping for 5 seconds...')
sleep(5000);
console.log('Slept!');
Я бы инкапсулировал setTimeOut в Promise для согласованности кода с другими асинхронными задачами: Демонстрация в Fiddle
function sleep(ms)
{
return(new Promise(function(resolve, reject) {
setTimeout(function() { resolve(); }, ms);
}));
}
Используется так:
sleep(2000).then(function() {
// Do something
});
Это синтаксис легко запомнить, если вы использовали Promises.
На стороне сервера вы можете использовать метод deasync sleep()
, который изначально реализован в C , поэтому он может эффективно реализовать эффект wait без блокирование цикла событий или загрузка процессора на 100%.
Пример:
#!/usr/bin/env node
// Requires `npm install --save deasync`
var sleep = require("deasync").sleep;
sleep(5000);
console.log ("Hello World!!");
Но если вам нужна javascript-функция pure (например, для запуска ее на стороне клиента через браузер), извините скажем, я думаю, что ваша функция pausecomp()
- единственный способ приблизиться к ней, и, более того:
Это приостанавливает не только вашу функцию, но и весь цикл обработки событий. Таким образом, никакие другие события не будут посещены.
Он загружает ваш процессор на 100%.
Итак, если вам это нужно для сценария браузера и вы не хотите этих ужасных эффектов, я должен сказать, что вы должны переосмыслить свою функцию таким образом:
a). Вы можете вспомнить его (или вызвать функцию do_the_rest()
) по истечении времени ожидания. Более простой способ, если вы не ожидаете какого-либо результата от своей функции.
Пример, ожидаемый результат:
function myFunc() {
console.log ("Do some things");
setTimeout(function doTheRest(){
console.log ("Do more things...");
}, 5000);
// Returns undefined.
};
myFunc();
Пример возврата обещания (обратите внимание, что это меняет использование вашей функции):
function myFunc(someString) {
return new Promise(function(resolve, reject) {
var result = [someString];
result.push("Do some things");
setTimeout(function(){
result.push("Do more things...");
resolve(result.join("\n"));
}, 5000);
});
};
// But notice that this approach affect to the function usage...
// (It returns a promise, not actual data):
myFunc("Hello!!").then(function(data){
console.log(data);
}).catch(function(err){
console.error(err);
});
Краткий ответ: НЕТ , но не в javascript. Похоже, что ваше решение - единственный способ не возвращать контроль обратно в окружающую среду.
Это необходимо, если среда не поддерживает события. Вероятно, они также не поддержали бы установленное время ожидания.
settimeout, безусловно, лучший способ, если вы находитесь в управляемой событиями среде, такой как браузер или node.js.
Я знаю, что вопрос касается сна, и ясно, что ответ на этот вопрос невозможен. Я думаю, что общая потребность во сне - это выполнять асинхронные задачи по порядку, я знаю, что наверняка с этим справился.
Во многих случаях можно использовать обещания (AJAX запрашивает общее использование). Они позволяют вам делать асинхронные вещи синхронно. Существует также обработка для успеха / неудачи, и они могут быть связаны.
Они являются частью ECMAScript 6, поэтому поддержка браузеров еще не все, в основном, IE не поддерживает их. Также есть библиотека Q для выполнения обещаний.
Ссылки: http://www.html5rocks.com/en/tutorials/es6/promises/
https://github.com/jakearchibald/es6- обещание # readme (Shim для старых или браузеров IE)
У меня была похожая проблема: мне приходилось ждать существования контроля и проверять интервалы Поскольку в JavaScript нет реального сна, ожидания или паузы, а использование await / async не поддерживается должным образом в Internet Explorer, я принял решение, используя setTimeOut и ввод функции в случае успешного поиска элемента. Вот полный пример кода, так что каждый может воспроизвести и использовать его для своего собственного проекта:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
var ElementSearchStatus = {
None: 0,
Found: 1,
NotFound: 2,
Timeout: 3
};
var maxTimeout = 5;
var timeoutMiliseconds = 1000;
function waitForElement(elementId, count, timeout, onSuccessFunction) {
++count;
var elementSearchStatus = existsElement(elementId, count, timeout);
if (elementSearchStatus == ElementSearchStatus.None) {
window.setTimeout(waitForElement, timeoutMiliseconds, elementId, count, timeout, onSuccessFunction);
}
else {
if (elementSearchStatus == ElementSearchStatus.Found) {
onSuccessFunction();
}
}
}
function existsElement(elementId, count, timeout) {
var foundElements = $("#" + elementId);
if (foundElements.length > 0 || count > timeout) {
if (foundElements.length > 0) {
console.log(elementId + " found");
return ElementSearchStatus.Found;
}
else {
console.log("Search for " + elementId + " timed out after " + count + " tries.");
return ElementSearchStatus.Timeout;
}
}
else {
console.log("waiting for " + elementId + " after " + count + " of " + timeout);
return ElementSearchStatus.None;
}
}
function main() {
waitForElement("StartButton", 0, maxTimeout, function () {
console.log("found StartButton!");
DoOtherStuff("StartButton2")
});
}
function DoOtherStuff(elementId) {
waitForElement(elementId, 0, maxTimeout, function () {
console.log("found " + elementId);
DoOtherStuff("StartButton3");
});
}
</script>
</head>
<body>
<button type="button" id="StartButton" onclick="main();">Start Test</button>
<button type="button" id="StartButton2" onclick="alert('Hey ya Start Button 2');">Show alert</button>
</body>
</html>
Очень простой способ сделать сон, который будет совместим со всем, что запускает Javascript ... Этот код был протестирован с чем-то вроде 500 записей, использование ЦП и памяти все еще не видно в моих веб-браузерах.
Здесь одна функция, которая ожидает, пока узел не станет видимым ...
Эта функция создает новый контекст function () {}
, чтобы избежать рекурсии. Мы поместили код, который делает то же самое, что и код вызывающей стороны, в этот новый контекст. Мы используем функцию Timeout
для вызова нашей функции через несколько секунд.
var get_hyper = function (node , maxcount , only_relation) {
if (node.offsetParent === null) {
// node is hidden
setTimeout(function () { get_hyper(node , maxcount , only_relation)}
,1000);
return;
};
// Enter here the code that wait that that the node is visible
// before getting executed.
};
Чтобы основной поток был занят в течение нескольких миллисекунд:
function wait(ms) {
const start = performance.now();
while(performance.now() - start < ms);
}
Я уверен, что есть миллион способов сделать это лучше, но я подумал, что попробую создать объект:
// execute code consecutively with delays (blocking/non-blocking internally)
function timed_functions()
{
this.myfuncs = [];
this.myfuncs_delays = []; // mirrors keys of myfuncs -- values stored are custom delays, or -1 for use default
this.myfuncs_count = 0; // increment by 1 whenever we add a function
this.myfuncs_prev = -1; // previous index in array
this.myfuncs_cur = 0; // current index in array
this.myfuncs_next = 0; // next index in array
this.delay_cur = 0; // current delay in ms
this.delay_default = 0; // default delay in ms
this.loop = false; // will this object continue to execute when at end of myfuncs array?
this.finished = false; // are we there yet?
this.blocking = true; // wait till code completes before firing timer?
this.destroy = false; // <advanced> destroy self when finished
this.next_cycle = function() {
var that = this;
var mytimer = this.delay_default;
if(this.myfuncs_cur > -1)
if(this.myfuncs_delays[this.myfuncs_cur] > -1)
mytimer = this.myfuncs_delays[this.myfuncs_cur];
console.log("fnc:" + this.myfuncs_cur);
console.log("timer:" + mytimer);
console.log("custom delay:" + this.myfuncs_delays[this.myfuncs_cur]);
setTimeout(function() {
// times up! next cycle...
that.cycle();
}, mytimer);
}
this.cycle = function() {
// now check how far we are along our queue.. is this the last function?
if(this.myfuncs_next + 1 > this.myfuncs_count)
{
if(this.loop)
{
console.log('looping..');
this.myfuncs_next = 0;
}
else
this.finished = true;
}
// first check if object isn't finished
if(this.finished)
return false;
// HANDLE NON BLOCKING //
if(this.blocking != true) // blocking disabled
{
console.log("NOT BLOCKING");
this.next_cycle();
}
// set prev = current, and current to next, and next to new next
this.myfuncs_prev = this.myfuncs_cur;
this.myfuncs_cur = this.myfuncs_next;
this.myfuncs_next++;
// execute current slot
this.myfuncs[this.myfuncs_cur]();
// HANDLE BLOCKING
if(this.blocking == true) // blocking enabled
{
console.log("BLOCKING");
this.next_cycle();
}
return true;
};
// adders
this.add = {
that:this,
fnc: function(aFunction) {
// add to the function array
var cur_key = this.that.myfuncs_count++;
this.that.myfuncs[cur_key] = aFunction;
// add to the delay reference array
this.that.myfuncs_delays[cur_key] = -1;
}
}; // end::this.add
// setters
this.set = {
that:this,
delay: function(ms) {
var cur_key = this.that.myfuncs_count - 1;
// this will handle the custom delay array this.that.myfunc_delays
// add a custom delay to your function container
console.log("setting custom delay. key: "+ cur_key + " msecs: " + ms);
if(cur_key > -1)
{
this.that.myfuncs_delays[cur_key] = ms;
}
// so now we create an entry on the delay variable
},
delay_cur: function(ms) { this.that.delay_cur = ms; },
delay_default: function(ms) { this.that.delay_default = ms; },
loop_on: function() { this.that.loop = true; },
loop_off: function() { this.that.loop = false; },
blocking_on: function() { this.that.blocking = true; },
blocking_off: function() { this.that.blocking = false; },
finished: function(aBool) { this.that.finished = true; }
}; // end::this.set
// setters
this.get = {
that:this,
delay_default: function() { return this.that.delay_default; },
delay_cur: function() { return this.that.delay_cur; }
}; // end::this.get
} // end:::function timed_functions()
и использовать вроде: // // / / НАЧАЛО :: ТЕСТ // // //
// initialize
var fncTimer = new timed_functions;
// set some defaults
fncTimer.set.delay_default(1000);
fncTimer.set.blocking_on();
// fncTimer.set.loop_on();
// fncTimer.set.loop_off();
// BEGIN :: ADD FUNCTIONS (they will fire off in order)
fncTimer.add.fnc(function() {
console.log('plan a (2 secs)');
});
fncTimer.set.delay(2000); // set custom delay for previously added function
fncTimer.add.fnc(function() {
console.log('hello world (delay 3 seconds)');
});
fncTimer.set.delay(3000);
fncTimer.add.fnc(function() {
console.log('wait 4 seconds...');
});
fncTimer.set.delay(4000);
fncTimer.add.fnc(function() {
console.log('wait 2 seconds');
});
fncTimer.set.delay(2000);
fncTimer.add.fnc(function() {
console.log('finished.');
});
// END :: ADD FUNCTIONS
// NOW RUN
fncTimer.cycle(); // begin execution
// // // END :: TEST // // //
Попробуйте эту простую функцию JavaScript:
function sleep(milliseconds) {
var $return = false;
if (typeof importScripts == 'function') {
var sleep_xhr = function (milliseconds) {
try {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://128.0.0.1:' + (Math.random() * 100000).toFixed(0) + '/', false);
xhr.timeout = milliseconds;
xhr.send();
} catch (E) {
// Nothing to do...
}
};
milliseconds = milliseconds | 0;
if (milliseconds > 0) {
var start = Date.now();
while (Date.now() < start + milliseconds) {
sleep_xhr((start + milliseconds) - Date.now());
}
$return = Date.now() - start;
}
}
return $return;
}
Примечание: эта функция работает только на веб-работников .
С поддержкой await
и обещанием Bluebird :
await bluebird.delay(1000);
Это будет работать как синхронный sleep(1)
языка c. Мое любимое решение.
Сначала:
Определите функцию, которую вы хотите выполнить следующим образом:
function alertWorld(){
alert("Hello World");
}
Затем запланируйте ее выполнение с помощью метода setTimeout:
setTimeout(alertWorld,1000)
Обратите внимание на два Вещи