Поочередное выполнение функций



  • Читал в другой теме, что против callback hell в языке BAS сделано расширение - знак !. Но почему-то данная конструкция не работает, как нужно:

    BASExtended.prototype.test1 = function () {
    sleep(2000)!
    log('1');
    };
    BASExtended.prototype.test2 = function () {
    sleep(2000)!
    log('2');
    };
    BASExtended.prototype.test3 = function () {
    sleep(2000)!
    log('3');
    };
    BASExtended.prototype.test4 = function () {
    sleep(2000)!
    log('4');
    };
    BASExtended.prototype.test = function (callback) {
    BE.c = callback;
    BE.test1()!
    BE.test2()!
    BE.test3()!
    BE.test4()!
    BE.c();
    };
    BASExtended.prototype.main = function () {
    /Browser/
    eval('var t = function () {BE.test(function(){log('callback')});};');
    t()!
    };
    BE = new BASExtended();

    В цикле вызывается
    _call(BE.main, null, function(){sleep(BE.delay * 1000, function(){})})!
    в лог пишет следующее:

    [03:20:18] Поток №1 : 1
    [03:20:21] Поток №1 : 1
    [03:20:24] Поток №1 : 1
    [03:20:27] Поток №1 : 1
    [03:20:30] Поток №1 : 1
    [03:20:33] Поток №1 : 1
    [03:20:36] Поток №1 : 1
    [03:20:39] Поток №1 : 1

    Все работает нормально, если выполнять функцию test так:

    BASExtended.prototype.test = function (callback) {
    BE.c = callback;
    log('0');
    sleep(2000)!
    log('1');
    sleep(2000)!
    log('2');
    sleep(2000)!
    log('3');
    sleep(2000)!
    log('4');
    sleep(2000)!
    BE.c();
    };

    В логе соответственно

    [03:06:36] Поток №1 : 0
    [03:06:38] Поток №1 : 1
    [03:06:41] Поток №1 : 2
    [03:06:43] Поток №1 : 3
    [03:06:45] Поток №1 : 4
    [03:06:47] Поток №1 : callback
    [03:06:48] Поток №1 : 0
    [03:06:50] Поток №1 : 1
    [03:06:52] Поток №1 : 2
    [03:06:54] Поток №1 : 3
    [03:06:56] Поток №1 : 4
    [03:06:58] Поток №1 : callback

    Т.е. если цепочка функций больше 3, то "!" не работает.

    Но у меня в коде есть функции, расширяющие функционал BAS, и они вызываются из других функций, примерно так же, как я написал в нерабочем примере. Можно ли как-то это исправить с моей стороны? может, я чего-то не знаю, и нужно поменять мой код.


  • administrators

    @blackhacker

    1. Каждый раз вызывая асинхронную функцию вы должны делать это через _call. Например

    _call(test,null)!

    1. Если нужно передать в нее аргументы - передавайте их вторым параметром.
      _call(test, 1)!
      или
      _call(test, function(){log("test")})!

    Чтобы получить аргументы используйте функцию _arguments()

    Используя эти 2 правила я переписал код таким образом

    
    test1 = function () {
        sleep(200)!
        log('1');
    };
    test2 = function () {
        sleep(200)!
        log('2');
    };
    test3 = function () {
        sleep(200)!
        log('3');
    };
    test4 = function () {
        sleep(2000)!
        log('4');
    };
    test = function () {
        _CALLBACK_TEST = _arguments();
        _call(test1, null)!
        _call(test2, null)!
        _call(test3, null)!
        _call(test4, null)!
        _call(_CALLBACK_TEST,null)!
    };
    
    t = function () {
        _call(test, function(){log('callback')} )!
    }
    
    
    main = function () {
        t()!
    };
    
    _call(main,null)!
    log("end")
    

    Теперь вызов функции main разботает в цикле, с условиями и где угодно.



  • @support Спасибо за хорошие и подробные ответы во всех моих темах, теперь почти весь мой код работает) Но есть еще вопрос, как получить результат выполнения асинхронной функции? Будет ли работать _result(), если совершить return из такой функции? И будут ли работать блоки try\catch с асинхронными функциями?


  • administrators

    @blackhacker

    как получить результат выполнения асинхронной функции? Будет ли работать _result(), если совершить return из такой функции

    Нужно использовать функцию _set_result(), вот пример кода

    function test()
    {
         sleep(1000)!
         _set_result("test")
    }
    _call(test,null)!
    log(_result())
    

    try\catch будет работать только с синхронным кодом, для асинхронного можно использовать функцию _on_fail вот пример

    function FunctionWhichAlwaysFail()
    {
        load("ldkjfgsldgkdg.com")!
    }
    
    //try
    _call(function()
    {
        //catch
         _on_fail(function(){
              log("Ошибка : " + _result())
              _break()
         })
    
         _call(FunctionWhichAlwaysFail,null)!
    
         log("Это никогда не будет выведено")
    
    },null)!
    
    log("конец")
    


  • @blackhacker , @support как нужно изменить этот код

    var j = 1;
    mark1:
    while(true){
      log("Итерация: " + j)
      for(var i=0; i<VAR_LIST_ACCS.length; i++){
        var tmpArr = VAR_LIST_ACCS[i][14].split("#");
        var cntUploads = parseInt(tmpArr[0]);
        var scheduleUploads = JSON.parse(tmpArr[1]);
        if( cntUploads != scheduleUploads.length-1 && Date.now() + timeZones[VAR_LIST_ACCS[i][5].split("#")[0]] >= scheduleUploads[cntUploads] ) {
          VAR_LIST_ACCS[i][14] = cntUploads + 1 + "#" + JSON.stringify(scheduleUploads);
          log("найден: " + VAR_LIST_ACCS[i][4]);
          break mark1;
        }
        sleep(500)!
      }
      j++;
      sleep(15000)!
    }
    
    

    в этом цикле идет проверка дат, по условию, когда нужный момент времени/даты наступил выходим из цикла.
    У меня проблема с sleep()! паузы не работают, БАС подвисает на этом цикле. Точнее БАС то работает, но интерфейс не отвечает, как выполнить паузы в тех местах цикла?



  • @support кстати, вопрос по "теме будет".

    Пробую вызвать:
    alt text

    Где alt text

    Получаю ошибку:
    alt text

    Что я делаю не так? Если вызывать код, внутри getNewBotData(), без самой функции getNewBotData, все работает замечательно.

    Однако когда все это оборачиваю в функцию getNewBotData и пытаюсь ее вызвать через _call, умирает :(



  •         j = 1;
        _do(function () {
            log("Итерация: " + j);
            _do(function () {
                VAR_CYCLE_INDEX = _iterator() - 1;
                if (VAR_CYCLE_INDEX > VAR_LIST_ACCS.length - 1) {
                    _break();
                }
                var tmpArr = VAR_LIST_ACCS[VAR_CYCLE_INDEX][14].split("#");
                var cntUploads = parseInt(tmpArr[0]);
                var scheduleUploads = JSON.parse(tmpArr[1]);
                if (cntUploads != scheduleUploads.length - 1 && Date.now() + timeZones[VAR_LIST_ACCS[VAR_CYCLE_INDEX][5].split("#")[0]] >= scheduleUploads[cntUploads]) {
                    VAR_LIST_ACCS[VAR_CYCLE_INDEX][14] = cntUploads + 1 + "#" + JSON.stringify(scheduleUploads);
                    log("найден: " + VAR_LIST_ACCS[VAR_CYCLE_INDEX][4]);
                    _break(2);
                }
                sleep(500)!
            })!
            j++;
            sleep(15000)!
        })!
    


  • @blackhacker said in Поочередное выполнение функций:

    erato

    спасибо!
    на счет break, то там по идее должен сработать такой: _break(2);


  • administrators

    @out Если внутри используются асинхронные функции, то if нужно заменять на _if, for и while на _do

    Я бы сделал так.

        _do(function () {
            log("Итерация: " + _iterator());
            _do(function () {
                   if (_iterator() > 3) {
                     _break();
                    }
                    var r = rand(1,100)
                    log(r)
                    if(r>95)
                    {
                        log("найдено");
                        _break(2);
                    }
                })!
                sleep(500)!
            })!
    

  • administrators

    @blackhacker Извините, случайно отредактировал ваш пост. Частично восстановил.



  • @support да ничего, все равно у меня неправильно было с _if. Хотел переделать раньше, но забыл. хотя там в if асинхронного кода нет вроде.


Log in to reply
 

Looks like your connection to Bablosoft was lost, please wait while we try to reconnect.