2016-01-05 2 views
3

Я отстраняюсь от цепочки двух обещаний внутри цикла, так что обещание номер два не начинается до тех пор, пока обещание не будет разрешено.Последовательное выполнение обещаний внутри цикла for

Я видел пример с уменьшением. Не удалось заставить его работать. Если я просто сделаю то, что у меня есть, код будет выполняться параллельно - как и в случае, все асинхронные запросы запускаются, и, конечно, результаты перепутаны. Пожалуйста, обратите внимание:

for (var i = 0; i < dummyData.accounts.length; i++) { 
    var cursorUser = dummyData.accounts[i]; 
    var auth0User = { 
    email: cursorUser.email, 
    password: 'abc123', 
    connection: 'Username-Password-Authentication' 
    }; 
    createUser(api, auth0User) 
    .then(function (auth0Info) { 
     return auth0Info; 
    }) 
    .then(function(auth0Info) { 
     cursorUser.authProfile = auth0Info; 
     console.log("account: ", cursorUser); 
     return create(accountsAPIService, cursorUser); 
    }) 
} 
+0

См [все] метод (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all). – Vidul

+0

Какая версия узла это? –

ответ

2

См @Tomalak's answer для фактического решения.


Проблема заключается в том, что положение for не создает новую область видимости для переменных. Другими словами, вы код понимается как:

var i, cursorUser, auth0User; 
for (i = 0; i < dummyData.accounts.length; i++) { 
    cursorUser = dummyData.accounts[i]; 
    auth0User = { 
    // ... 
    }; 
    // ... 
} 

Когда асинхронная обещание будет решена еще одна итерация, вероятно, уже переписаны переменную cursorUser: then обратного вызова не может прочитать значение итерации, которая начала свое обещание больше.

+1

Это технически правильно, но, к сожалению, не очень элегантно. Нет необходимости мириться с циклами 'for' в асинхронных контекстах. – Tomalak

+0

@Tomalak Вы абсолютно правы, просмотрите код FTW :) – sp00m

+0

Я не решался перефразировать ваш ответ в моих, поэтому я этого не сделал. Хороший компромисс. – Tomalak

4

Просто избегайте for петель для асинхронной работы.

Массивы имеют функциональные методы, такие как forEach и map для такого рода вещей.

var pendingResults = dummyData.accounts.map(function (account) { 
    return createUser(api, { 
     email: account.email, 
     password: 'abc123', 
     connection: 'Username-Password-Authentication' 
    }).then(function (authInfo) { 
     console.log("account: ", authInfo); 
     return create(accountsAPIService, authInfo); 
    }); 
}); 

Promise.all(pendingResults).then(function (results) { 
    // everything is done 
}); 
+0

Мне это нравится. Спасибо. попытаюсь. –

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