Как преобразовать вложенные setTimeouts в обещания

Используя rsvp.js или любую другую реализацию обещаний /A+, как я могу превратить код, как...

console.log('step 1');
setTimeout(function() {
  console.log('step 2');
  setTimeout(function() {
    console.log('step 3');
  }, 100);
}, 300);

в реализации обещаний?

4 ответа

Решение

Создайте функцию задержки, которая возвращает Обещание и фактически разрешает его по истечении заданного времени в setTimeout, как это

function delay(time) {
    return new RSVP.Promise(function (resolve) {
        setTimeout(resolve, time);
    });
}

и тогда вы можете вызвать это так

console.log("step 1");
delay(3000)
    .then(function () {
        console.log("step 2");
        return delay(1000);
    })
    .then(function () {
        console.log("step 3");
    });

Если вы согласны с использованием q, в библиотеку встроено очень простое решение:

console.log('step 1');
Q.delay(300).then(function() {
    console.log('step 2');
    return Q.delay(200);
}).then(function() {
    console.log('step 3');
});

Цепочка обещаний:

// Set up the functions which contain the promises
function step1() {
    return new RSVP.Promise(function(resolve, reject) {
        resolve();
    });
}

function step2() {
    return new RSVP.Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve();
        }, 300);
    });
}

function step3() {  
    return new RSVP.Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve();
        }, 100);
    });
}

// Now execute them:
step1()
    .then(step2)
    .then(step3)

Вы можете прочитать больше здесь: http://www.toptal.com/javascript/javascript-promises

Следуйте правилам большого пальца для развития обещания! Прежде всего, нам нужно обещать setTimeout вызовов, так что мы получаем функцию, которая возвращает нам обещание для этого. С RSVP Promise конструктор, это будет выглядеть так:

function delay(time) {
    return new RSVP.Promise(function(resolve) {
        setTimeout(resolve, time);
    });
}

Теперь мы можем связать операторы журнала, используя then вместо того, чтобы передать обратный вызов прямо в setTimeout:

console.log("step 1");
delay(3000).then(function() {
    console.log("step 2");
    return delay(1000).then(function() {
        console.log("step 3");
    });
});

... и получите обещание, когда все три шага будут выполнены.

Однако актуальная особенность then в том, что теперь вы можете откатить обратные вызовы и получить точно такой же результат. Итак, ваша цепочка будет выглядеть так:

console.log("step 1");
delay(3000).then(function() {
    console.log("step 2");
    return delay(1000);
}).then(function() {
    console.log("step 3");
});
Другие вопросы по тегам