Добавить метод сна в цепочку методов объекта (JS)

Я пытаюсь добавить в объект метод сна, который можно вызвать в середине цепочки методов. Я решил использовать setTimeout (), но поток javascript не может быть заблокирован, и он не может выводить нужный мне порядок.

<div id="test"></div>

 function hello(str){
  var text = document.getElementById("text");
  this.eat = function(kind){
    text.innerHTML += "<p>Eat "+ kind + "</p>";
    return this;
  }
  this.sleep = function(delay){
    setTimeout(function(){
      text.innerHTML += "<p>Sleep "+delay + "</p>";
    }, delay);
    return this;
  }
  text.innerHTML += "<p>Hello, "+ str + "</p>";
  return this;
}
var test = hello("guy").sleep(3000).eat("dinner"); 
/* I want an output as: 
      Hello, guy -> (wait 3 secs) Sleep 3000 -> Eat dinner
   But actually the output is:
      Hello, guy -> Eat dinner -> (wait 3 secs) Sleep 3000    
*/  

Есть у кого-нибудь идеи по этому поводу? Должен ли я использовать прототип или какие-то другие способы с этим справиться? Более того, если я хочу добавить в этот объект еще один метод с именем sleepFirst. Когда я называю это так:

var test2 = hello("boys").sleepFirst(2000).eat("lanch")

он выводит:
(подождите 2 секунды) sleepFirst 2000 -> Hello, boys -> Eat lanch

Что мне делать?
(Постскриптум: я новичок в веб-разработке, возможно, кто-то уже задавал аналогичный вопрос раньше, но я долго искал и не мог найти его T ^ T Я китаец и извините, что мой английский может показаться не очень хорошим. Спасибо ~~)


person little_tao_    schedule 10.04.2015    source источник
comment
Интересный вопрос. JS является асинхронным, поэтому один из способов сделать это - добавить обратный вызов к вашему методу сна, хотя тогда это не будет цепочкой. Другой способ - это система очередей stackoverflow.com/questions/14365318/   -  person rdiz    schedule 10.04.2015
comment
@ArK О да! Способ очереди работоспособен!   -  person little_tao_    schedule 10.04.2015


Ответы (1)


@RobG убедил меня переписать ваш фрагмент кода, используя определение реального объекта. JsFiddle здесь.

var sleeper = {
    text: document.getElementById("text"),
    eat: function (kind) {
        text.innerHTML += "<p>Eat " + kind + "</p>";
        return this;
    },
    sleep: function (delay, func, param) {
        setTimeout(function () {
            func(param);
            //text.innerHTML += "<p>Sleep " + delay + "</p>";
        }, delay);
        return this;
    },
    hello: function (str) {
        text.innerHTML += "<p>Hello, " + str + "</p>";
        return this;
    }
};

sleeper.hello("guy").sleep(3000, sleeper.eat, "dinner");

Это намного лучше. Но таким образом вы не сможете выполнить цепочку из более чем одного вызова.

person Amessihel    schedule 10.04.2015
comment
Обратите внимание, что this ссылается на глобальный объект, вероятно, это не то, что вы ожидаете, this.sleep = ...; создает глобальное свойство, и вы продолжаете возвращать this, который является глобальным объект, поэтому ваш код эквивалентен hello('guy'); sleep(...);. Попытайся. - person RobG; 10.04.2015
comment
[отредактировано, потому что вы отредактировали свои ответы.] Вы правы, я просто изменил этот код, чтобы сделать его рабочим, а не эффективным. - person Amessihel; 10.04.2015
comment
@Amessihel Спасибо! Также мне предложили использовать очередь, чтобы справиться с этим, и я считаю, что это работоспособный способ ссылка - person little_tao_; 10.04.2015
comment
Ага, я это видел! Вы также можете создать функцию следующим образом: function sleepyRun(delay1, call1, delay2, call2, ...) Вы можете управлять функциями с неограниченным количеством аргументов. См. [developer.mozilla.org/fr/ docs / Web / JavaScript / Reference /, если вы хотите проверить это так. - person Amessihel; 10.04.2015