Для людей, которые используют AngularJS , может справиться с этой ситуацией, используя Promises
.
Здесь it говорит,
Обещания могут использоваться для отключения асинхронных функций и позволяют объединять несколько функций вместе.
Вы можете найти приятное объяснение здесь .
Пример, найденный в docs , упомянутом ниже.
promiseB = promiseA.then( function onSuccess(result) { return result + 1; } ,function onError(err) { //Handle error } ); // promiseB will be resolved immediately after promiseA is resolved // and its value will be the result of promiseA incremented by 1.
Angular2 and Later
In
Angular2
, посмотрите на следующий пример, но его рекомендовал использоватьObservables
сAngular2
.search(term: string) { return this.http .get(`https://api.spotify.com/v1/search?q=${term}&type=artist`) .map((response) => response.json()) .toPromise();
}
Вы можете использовать это таким образом,
search() { this.searchService.search(this.searchField.value) .then((result) => { this.result = result.artists.items; }) .catch((error) => console.error(error)); }
См. здесь оригинал . Но TypScript не поддерживает native es6 Promises , если вы хотите его использовать, для этого вам может понадобиться плагин.
Кроме того, здесь представлены обещания spec определите здесь.
В вашем коде в настоящее время состояние гонки , поэтому результат неверен. Чтобы проиллюстрировать, почему это так, воспользуемся простым примером:
Вы работаете в 2 потоках, а массив - int input[4] = {1, 2, 3, 4};
. Вы правильно инициализируете sum
до 0
и готовы к запуску цикла. На первой итерации вашего цикла поток 0 и поток 1 читают sum
из памяти как 0
, а затем добавьте их соответствующий элемент в sum
и запишите его обратно в память. Однако это означает, что поток 0 пытается записать sum = 1
в память (первый элемент - 1
и sum = 0 + 1 = 1
), а поток 1 пытается записать sum = 2
в память (второй элемент - 2
и sum = 0 + 2 = 2
). Конечный результат этого кода зависит от того, какой из последних заканчивается последним, и поэтому записывает в память последним, что является условием гонки. Не только это, но и в этом конкретном случае ни один из ответов, которые мог бы произвести код, правильный! Есть несколько способов обойти это; Ниже я расскажу о трех основных:
#pragma omp critical
:
В OpenMP существует так называемая директива critical
. Это ограничивает код так, что только один поток может что-то делать за раз. Например, ваш for
-loop может быть записан:
#pragma omp parallel for schedule(static)
for(i = 0; i < snum; i++) {
int *tmpsum = input + i;
#pragma omp critical
sum += *tmpsum;
}
Это устраняет условие гонки, когда только один поток обращается и записывается в sum
за раз. Тем не менее, директива critical
очень плоха для производительности и, вероятно, убьет большую часть (если не все) выгоды, получаемой от использования OpenMP в первую очередь.
#pragma omp atomic
:
Директива atomic
очень похожа на директиву critical
. Основное отличие состоит в том, что, хотя директива critical
применяется ко всему, что вы хотели бы сделать по одному потоку за раз, директива atomic
применяется только к операциям чтения / записи памяти. Поскольку все, что мы делаем в этом примере кода, - это чтение и запись для суммирования, эта директива будет работать отлично:
#pragma omp parallel for schedule(static)
for(i = 0; i < snum; i++) {
int *tmpsum = input + i;
#pragma omp atomic
sum += *tmpsum;
}
Производительность atomic
обычно значительно лучше, чем у critical
. Тем не менее, это еще не лучший вариант в вашем конкретном случае.
reduction
:
Метод, который вы должны использовать, и метод, который уже был предложен другими, - это reduction
. Вы можете сделать это, изменив for
-loop на:
#pragma omp parallel for schedule(static) reduction(+:sum)
for(i = 0; i < snum; i++) {
int *tmpsum = input + i;
sum += *tmpsum;
}
Команда reduction
сообщает OpenMP, что, хотя цикл работает, вы хотите, чтобы каждый поток отслеживал свои собственные sum
и добавить их все в конце цикла. Это самый эффективный метод, так как весь цикл теперь выполняется параллельно, при этом единственные служебные данные находятся прямо в конце цикла, когда необходимо добавить значения sum
каждого из потоков.
Используйте предложение reduction
( в MSDN ).
int* input = (int*) malloc (sizeof(int)*snum);
int sum = 0;
int i;
for(i=0;i<snum;i++){
input[i] = i+1;
}
#pragma omp parallel for schedule(static) reduction(+:sum)
for(i=0;i<snum;i++)
{
sum += input[i];
}