2016-02-02 2 views
3

У меня есть образец кода, где я не мог предсказать поток кода.Как предсказать асинхронный характер обещаний

var x =() => { 
    return new Promise((resolve, reject) => { 
    setTimeout(() => { 
     resolve([1, 2, 3]); 
    }, 0); 
    }); 
}; 

x().then((val) => { 
    console.log(val); 
}).catch((err) => { 
    console.log(err.message); 
}); 

console.log("hello"); 

for (var i = 0; i < 10; i++) { 
    console.log(i); 
} 

var y = Promise.all([Promise.resolve(1), Promise.reject(Error("err"))]); 

y.then((arr) => { 
    console.log(arr); 
    }) 
    .catch((err) => { 
    console.log(err); 
    }); 

Promise.resolve('ta-da!') 
    .then((result) => { 
    console.log('Step 2 received ' + result); 
    return 'Greetings from step 2'; 
    }) 
    .then((result) => { 
    console.log('Step 3 received ' + result); 
    }) 
    .then((result) => { 
    console.log('Step 4 received ' + result); 
    return Promise.resolve('fulfilled value'); 
    }) 
    .then((result) => { 
    console.log('Step 5 received ' + result); 
    return Promise.resolve(); 
    }) 
    .then((result) => { 
    console.log('Step 6 received ' + result); 
    }); 

бревна в следующем порядке:

"hello" 
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
"Step 2 received ta-da!" 
"Step 3 received Greetings from step 2" 
"err" 
"Step 4 received undefined" 
"Step 5 received fulfilled value" 
"Step 6 received undefined" 
[1, 2, 3] 

для цикла становится выполнен, как и ожидалось. SetTimeout() работает как ожидалось, и обещание выполняется после цикла события.

Остальные 2 обещания сталкиваются. Я ожидал, обещания будут fulfulled сразу в syncronously и результат будет

"hello" 
    0 
    1 
    2 
    3 
    4 
    5 
    6 
    7 
    8 
    9 
    "err" 
    "Step 2 received ta-da!" 
    "Step 3 received Greetings from step 2" 
    "Step 4 received undefined" 
    "Step 5 received fulfilled value" 
    "Step 6 received undefined" 
    [1, 2, 3]. 

Даже если обещания будут решены async.How они столкнулись.

Снимок экрана прилагается.

enter image description here

+2

Шаг 3 не возвращает обещание, поэтому цепочка разбита, а остальная часть перемещается на следующую итерацию цикла событий (в отличие от планирования другой микрозадачи для немедленного выполнения). –

+0

@ MadaraUchiha Шаг 2 также не вернул обещание. – thefourtheye

+0

@thefourtheye вы можете объяснить, почему они сломаны. Это выглядит хорошо для меня. Журналы также говорят то же самое. – starkk92

ответ

1

У вас есть три отдельные цепи обещание в вашем коде:

  1. тот, который начинается с x() и занимает больше времени из-за тайм-аута
  2. тот, который начинается с y (от Promise.all(…)), где ошибка выдается
  3. тот, который начинается с Promise.resolve('ta-da!')

Они не ждут друг друга - лет ты не сказал им делать, и они не будут делать это магически.
Вместо этого их потоки произвольно перемежаются, как и для стандартных асинхронных функций (подумайте о двух setInterval s с разными периодами).

Я ожидал, что обещания будет fulfulled сразу в syncronously

No. Promise обратных вызовов являются всегда (надежно) асинхронные, даже если обещание уже решены.

1

Отвечу на Конструктивно вместо чистого тестирования, как это:

Цель обетование делать асинхронные запросы, такие как запросы к серверу, в parallell.

Таким образом, порядок их разрешения будет зависеть от ответов на сервер больше, чем на клиентском цикле javascript на broswer.

По дизайну поток любых запросов не является предсказуемым. Это справедливо для всех асинхронных.

Так что если вам нужно сделать один запрос, тогда вам нужно подождать, чтобы решить первое обещание, а затем сделать другое. Если вам нужны независимые операции, скажем, загружая панель с независимыми компонентами, вы можете одновременно запустить все ваши асинхронные запросы. У вас не будет проблем с каким бы то ни было решением, в случае с панелью управления, вы действительно заботитесь о том, чтобы первый компонент был загружен до второго, который отображает информацию, которая полностью независима? Конечно нет.

Теперь, если вы просто хотите узнать, как это реализовано в браузере, я бы просто сказал, что он, вероятно, изменится, если вы измените броузер, так что это совершенно не актуально. Вы должны сделать свой javascript более чем одним браузером.