Я не англичанин, но помогу вам с аккуратным решением Javascript для вашей проблемы.Ваша проблема - пример из учебника обещаний Javascript .В Javascript a Promise
- это объект, который может выдать одно значение в будущем .Я уверен, что вышеприведенное утверждение трудно понять, если вы никогда не слышали об этой концепции, но давайте подумаем со здравым смыслом.Promise
в Javascript не отличается от обещания в реальной жизни.Если я вам что-то обещаю, может произойти следующее:
- мое обещание уже выполнено в тот момент, когда я обещаю вам его, и в этом случае вы можете выполнить его
- мое обещаниебудет выполнено некоторое время спустя в будущем
- , в будущем будет очевидно, что мое обещание не было выполнено
- мое обещание никогда не будет оценено
ЭтиИнтуитивные случаи имеют аналогичные случаи в программировании, когда вы работаете с обещаниями.
Пример для обещания:
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000); // (*)
});
Пример взят из https://javascript.info/promise-chaining
Как видите,конструктор Promise получает параметр function
, который, в свою очередь, имеет параметр resolve
и reject
.И resolve
, и reject
являются functions
.resolve
вызывается при выполнении Promise
, тогда как reject
вызывается при отклонении Promise
.В нашем случае тело Promise
содержит вызов setTimeout
, который гарантирует, что Promise
будет разрешен на одну секунду позже, чем создание Promise
.
Итак, что если запрос является Promise
(интуитивно это обещание, что вы получите ответ, каким бы он ни был), а следующий запрос - это следующий Promise
и так далее?Есть ли способ связать обещания?Конечно, давайте посмотрим на полный пример:
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000); // (*)
}).then(function(result) { // (**)
alert(result); // 1
return result * 2;
}).then(function(result) { // (***)
alert(result); // 2
return result * 2;
}).then(function(result) {
alert(result); // 4
return result * 2;
});
Как вы, наверное, уже догадались, ваши запросы должны быть в теле обещаний, прикованных к вызову then () .Например:
function promiseBody(resolve, reject) {
// send request
// if successful, call resolve
// if failed, call reject
}
var prom = new Promise(promiseBody);
//this array contains requests to be called after the first
for (var req of requests) {
prom = prom.then(promiseBody);
}
Цепочка ваших обещаний выглядит очень аккуратно, ее легко понять и поддерживать.Конечно, это скорее теоретический ответ, потому что вам нужно будет определить, что resolve
, reject
, promiseBody
и requests
выглядят одинаково в вашем конкретном случае, а также вам нужно будет справиться с возможнымиВ ситуации, когда на один из запросов по какой-то причине никогда не будет получен ответ, но как только вы поймете, что у вас есть очень элегантный способ продолжить и вам просто нужно выяснить детали, вы окажетесь на правильном пути.
Конечно, вы можете решить эту проблему традиционным способом, связав обратные вызовы, но это не очень элегантно.Вы также можете решить эту проблему с помощью генераторов Javascript, и в результате вы получите что-то более элегантное, чем решение старой школы обратного вызова ( hell ), например:
function *myRequestHandler(request) {
while (request) {
send(request);
request = yield;
};
}
и гарантирующее передачуправильный request
, когда это вызывается и всякий раз, когда выполняется обратный вызов, вызывается next()
, передавая next
request
.