2016-04-08 2 views
2

Я играл с Promises, но у меня возникают проблемы с пониманием того, что происходит со следующим кодом:JavaScript Обещания и SetTimeout

function a() { 
    return new Promise(function (resolve, reject) { 
     resolve("hi from a!"); 
    }); 
} 

function b() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from b!"); 
     }, 5000); 
    }); 
} 

function c() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from c!"); 
     }, 1000); 
    }); 
} 

a().then(function (resultFromA) { 
    console.log("a() responded with: " + resultFromA); 
    b(); 
}).then(function (resultFromB) { 
    console.log("b() responded with: " + resultFromB); 
    c(); 
}).then(function (resultFromC) { 
    console.log("c() responded with: " + resultFromC); 
}); 

Я ожидаю, что это выход a() responded with: hi from a! немедленно, наряду с b() responded with: hi from b! и c() responded with: hi from c! после их соответствующие огни setTimeout(). Тем не менее, я немедленно получаю следующий вывод:

a() ответил: привет от a!

б() ответили не определено

с() в ответ на это не определено

Я думал, что .then() ждет на эти обещания, но это не так. Любая помощь будет оценена по достоинству.

ответ

12

return b() и return c() от ваших then обработчиков.

then только «заменяет» первое обещание последующим обещанием, которое является , возвращено из его обратного вызова.

Если then обратного вызова не return обещания, то then относится к первоначальному обещанию, и он будет выполнен немедленно, независимо от содержания/результата предыдущего then обратного вызова.

В основном ...

a().then(function() { 
    b() 
}).then(# This "then" is chained off of a's promise 

В то время как, наоборот:

a().then(function() { 
    return b() 
}).then(# This "then" is chained off of b's promise 
+0

Это объяснение неверно. Функция 'then()' всегда возвращает новое обещание. Однако в вышеприведенном случае ('b()') возвращаемое значение функции «undefined», которое завернуто в новое обещание. Похоже, второе обещание связано с обещанием 'a()', потому что тело функции .then() 'завершается синхронно, поэтому затем завершается немедленно. –

4

Вы должны return promises приковать них:

a().then(function (resultFromA) { 
    console.log("a() responded with: " + resultFromA); 
    // return b() promise 
    return b(); 
}).then(function (resultFromB) { 
    console.log("b() responded with: " + resultFromB); 
    // return c() promise 
    return c(); 
}).then(function (resultFromC) { 
    console.log("c() responded with: " + resultFromC); 
}); 
3

Вы забыли вернуться из вызова функции. Функция Javascript не возвращается неявно.

function a() { 
    return new Promise(function (resolve, reject) { 
     resolve("hi from a!"); 
    }); 
} 

function b() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from b!"); 
     }, 5000); 
    }); 
} 

function c() { 
    return new Promise(function (resolve, reject) { 
     setTimeout(function() { 
      resolve("hi from c!"); 
     }, 1000); 
    }); 
} 

a().then(function (resultFromA) { 
    console.log("a() responded with: " + resultFromA); 
    return b(); // return 
}).then(function (resultFromB) { 
    console.log("b() responded with: " + resultFromB); 
    return c(); // return 
}).then(function (resultFromC) { 
    console.log("c() responded with: " + resultFromC); 
}); 
+0

Моя проблема заключалась в том, что по какой-то причине я думал, что 'then' ждет всех обещаний в локальной области, чтобы разрешить, когда это действительно было только тот, который получает' return'ed. Я изначально не пытался выполнить 'return b()' или 'return c()'. –

+0

«Функция Javascript не возвращается неявно». Не совсем верно. Функции стрелок * do * возвращаются неявно, когда тело является одним выражением: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Function_body –

Смежные вопросы