Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Остановить цыкл после выполнения функции (https://javascript.ru/forum/dom-window/63866-ostanovit-cykl-posle-vypolneniya-funkcii.html)

EnVires 05.07.2016 10:13

Остановить цыкл после выполнения функции
 
top:
	for (var y = 0; y < global_Items.length; y++) {
	    if (global_Items[y]['market_name'].indexOf(iteam) != -1 && global_Items[y]['market_name'].indexOf('Сувенирный')== -1 && global_Items[y]['market_name'].indexOf('Сувенир')== -1) {
			console.log(global_Items[y]['market_name']);
	        var iditeam = global_Items[y]['classid'] + '_' + global_Items[y]['instanceid'];
	        getItem(iditeam, function(err, datak) {
	            if (!err) {					
					found = true;
	                name = global_Items[y]['market_name'];
	                price = datak['min_price'];
	                hash = datak['hash'];
					break top;
			    }
	        });

	    }

	}
}


Нужно после if (!err) { как то остановить цыкл,запущенный выше?Подскажите как это сделать

EnVires 06.07.2016 14:38

up

Яростный Меч 06.07.2016 16:36

а как работает getItem? что-то загружает с сервера?
если callback вызывается асинхронно, то надо убрать цикл, а каждую след. итерацию вызывать в callback, если "есть ошибка" (то есть в случае if (err))

EnVires 07.07.2016 10:12

да,получает ответ с сервера.Такая функция
request({
		   url: url, 
		   json: true
	    }, function (error, response, body) {
				body = JSON.parse(JSON.stringify(body));
				if(body.error === undefined) return callback(false,body);
			    else return callback(true,body);
	});

EnVires 07.07.2016 10:14

поподробней можно?

Яростный Меч 07.07.2016 12:17

примерно такъ (не проверял):

var findSomeItem = function findSomeItem(y, callback) {

    if (y < global_Items.length) {
        if (global_Items[y]['market_name'].indexOf(iteam) != -1 &&
            global_Items[y]['market_name'].indexOf('Сувенирный')== -1 &&
            global_Items[y]['market_name'].indexOf('Сувенир')== -1) {

            console.log(global_Items[y]['market_name']);
            var iditeam = global_Items[y]['classid'] + '_' + global_Items[y]['instanceid'];
            
            getItem(iditeam, function(err, datak) {
                if (!err) {					
                    found = true;
                    name = global_Items[y]['market_name'];
                    price = datak['min_price'];
                    hash = datak['hash'];
                    callback();
                } else {
                    findSomeItem(y + 1, callback);
                }
            });
        } else {
            findSomeItem(y + 1, callback);
        }
    } else {
        callback();
    }
};

findSomeItem(0, function() {
    // здесь выполняем дальнейший код, поиск завершен
    // ..
});

warren buffet 08.07.2016 13:34

Нельзя запускать асинхронные методы в синхронных мотоцЫклах. Цикл просто нахерачит столько запросов, сколько начитает и уже его кости сгниют, пока эти все запросы начнут валиться с сервера в хаотическом порядке причем. В таких делах ведущим является ответ сервера, а все остальное уже к нему цепляется. Например

/* _items ==  копия, 
если global_Items можно похерить, то его юзай прямо */
var _items=global_Items, 

next=function(err,datak) {

	/* если найдено, то запоздалые ответы сервера не обосрут малину */
	if(found) return true;

	if(!err && datak) {
		name = gitem['market_name'];
		price = datak['min_price'];
		hash = datak['hash'];
		return found = true; 
	}

	/* вытаскиваем по элемену из копии массива пока он не кончится */
	if(!gitem = _items.shift())
		return found=false;
	
	if (gitem['market_name'].indexOf(iteam) != -1 
		&& gitem['market_name'].indexOf('Сувенир')== -1 ) {

		/* и делаем запрос с колбэком на саму себя */
		getItem(gitem['classid']+'_'+gitem['instanceid'],next);
		
		return; /* следующую итерацию запустит ответ сервера */

	}
	else
		return next(); /* рекурсия */
		
};

/* запуск */
next();


Должно работать. Я сам слабо в таких делах волоку. )))

ЗЫ Но это все равно неправильно. Такой скрипт _должен_ что-то сделать, такое, конечное, окончательное. Он не может просто забить какие-то переменные данными, поскольку там, где они нужны, их ждут синхронно? То есть единственный асинхронный метод тянет за собой всю цепочку асинхрона до смертного одра.

EnVires 19.07.2016 20:35

Цитата:

Сообщение от warren buffet (Сообщение 421595)
Нельзя запускать асинхронные методы в синхронных мотоцЫклах. Цикл просто нахерачит столько запросов, сколько начитает и уже его кости сгниют, пока эти все запросы начнут валиться с сервера в хаотическом порядке причем. В таких делах ведущим является ответ сервера, а все остальное уже к нему цепляется. Например

/* _items ==  копия, 
если global_Items можно похерить, то его юзай прямо */
var _items=global_Items, 

next=function(err,datak) {

	/* если найдено, то запоздалые ответы сервера не обосрут малину */
	if(found) return true;

	if(!err && datak) {
		name = gitem['market_name'];
		price = datak['min_price'];
		hash = datak['hash'];
		return found = true; 
	}

	/* вытаскиваем по элемену из копии массива пока он не кончится */
	if(!gitem = _items.shift())
		return found=false;
	
	if (gitem['market_name'].indexOf(iteam) != -1 
		&& gitem['market_name'].indexOf('Сувенир')== -1 ) {

		/* и делаем запрос с колбэком на саму себя */
		getItem(gitem['classid']+'_'+gitem['instanceid'],next);
		
		return; /* следующую итерацию запустит ответ сервера */

	}
	else
		return next(); /* рекурсия */
		
};

/* запуск */
next();


Должно работать. Я сам слабо в таких делах волоку. )))

ЗЫ Но это все равно неправильно. Такой скрипт _должен_ что-то сделать, такое, конечное, окончательное. Он не может просто забить какие-то переменные данными, поскольку там, где они нужны, их ждут синхронно? То есть единственный асинхронный метод тянет за собой всю цепочку асинхрона до смертного одра.


и выдаст ошибку Maximum call stack size exceeded

warren buffet 20.07.2016 07:15

На js нет лимита рекурсии, это не пехепе, ограничения определяет сам браузер, какие у кого тут http://stackoverflow.com/questions/7...ack-size-limit

Но самый тупняк в том, что ты состаришься и твои внуки уже состарятся, пока стек переполнится в этой рекурсивной функции, которая запускает сама себя _после_ ответа сервера. Сервер-то отвечает за секунды, а не за микросекунды.

EnVires 20.07.2016 07:59

Цитата:

Сообщение от warren buffet (Сообщение 422670)
На js нет лимита рекурсии, это не пехепе, ограничения определяет сам браузер, какие у кого тут http://stackoverflow.com/questions/7...ack-size-limit

Но самый тупняк в том, что ты состаришься и твои внуки уже состарятся, пока стек переполнится в этой рекурсивной функции, которая запускает сама себя _после_ ответа сервера. Сервер-то отвечает за секунды, а не за микросекунды.

что же,на node.js этот код
var findSomeItem = function findSomeItem(y, callback) {

    if (y < global_Items.length) {
        if (global_Items[y]['market_name'].indexOf(iteam) != -1 &&
            global_Items[y]['market_name'].indexOf('Сувенирный')== -1 &&
            global_Items[y]['market_name'].indexOf('Сувенир')== -1) {

            console.log(global_Items[y]['market_name']);
            var iditeam = global_Items[y]['classid'] + '_' + global_Items[y]['instanceid'];
            
            getItem(iditeam, function(err, datak) {
                if (!err) {					
                    found = true;
                    name = global_Items[y]['market_name'];
                    price = datak['min_price'];
                    hash = datak['hash'];
                    callback();
                } else {
                    findSomeItem(y + 1, callback);
                }
            });
        } else {
            findSomeItem(y + 1, callback);
        }
    } else {
        callback();
    }
};

findSomeItem(0, function() {
    // здесь выполняем дальнейший код, поиск завершен
    // ..
});

выдает ошибку Maximum call stack size exceeded


Часовой пояс GMT +3, время: 19:48.