Как использовать ожидание и асинхронный поиск с помощью карты [duplicate]

Чтобы добавить к вопросу Стивена, а не рассуждать по-другому, важно , почему десятичный разделитель ..

Если это потому, что источник находится на компьютере -readable format, где разделитель десятичного числа периода указан как часть спецификации документа, тогда я бы пошел именно так, как это делает Стивен, используя CultureInfo.InvariantCulture.

Если это человеческий ввод в определенном языке, тогда вы хотел бы сопоставить этот язык с CultureInfo, подходящим для этого языка, иначе, если программное обеспечение используется с другим языком, у вас будет точно противоположная проблема. Как правило, вы хотите установить для потока CurrentCulture этот поток (CurrentCulture для форматов, CurrentUICulture для языков). Если вы это сделали, вам не нужно передавать культуру вообще, так как форма float.Parse(string) использует эту культуру, однако вы можете использовать float.Parse(string, CurrentCulture), чтобы быть явным, что это то, что вы делаете (и заткнуть некоторый программный анализ, который жалуется, когда вы не являетесь конкретным таким образом).

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

16
задан Felix Kling 1 March 2017 в 15:33
поделиться

2 ответа

Вы не можете сделать это, как вы себе представляете, потому что вы не можете использовать await, если он не находится непосредственно внутри функции async.

Разумная вещь здесь сделать функцию, переданную в map асинхронной. Это означает, что map вернет массив обещаний. Затем мы можем использовать Promise.all, чтобы получить результат, когда все обещания вернутся. Поскольку сам Promise.all возвращает обещание, внешняя функция не должна быть async.

const someFunction = (myArray) => {
    const promises = myArray.map(async (myValue) => {
        return {
            id: "my_id",
            myValue: await service.getByValue(myValue)
        }
    });
    return Promise.all(promises);
}
28
ответ дан lonesomeday 15 August 2018 в 20:14
поделиться
  • 1
    в этом случае массив обещаний не медленнее, чем классический для let в массиве? – stackdave 3 March 2018 в 07:38
  • 2
    @stackdave Возможно, но разница будет несущественной рядом с service.getByValue, что вполне может включать сетевой вызов ... – lonesomeday 3 March 2018 в 16:23
  • 3
    спасибо, что я начал использовать его, в любом случае читаемость лучше скорости, потому что большинство асинхронных методов ES6 всегда будут медленнее, но кто заботится – stackdave 3 March 2018 в 16:37

Я считаю, что это потому, что функция из map не является async , поэтому вы не можете ждать в ее возвратной инструкции. Он компилируется с этой модификацией:

const someFunction = async (myArray) => {
    return myArray.map(async (myValue) => { // <-- note the `async` on this line
        return {
            id: "my_id",
            myValue: await service.getByValue(myValue)
        }
    });
};

Попробуйте в Babel REPL

Итак ... невозможно дать рекомендации, не видя остальной части вашего app, но в зависимости от того, что вы пытаетесь сделать, либо сделайте функцию inner асинхронной, либо попытайтесь создать некоторую другую архитектуру для этого блока.

Обновление: мы могли бы получить на следующий день ожидается следующий уровень: https://github.com/MylesBorins/proposal-top-level-await

4
ответ дан helb 15 August 2018 в 20:14
поделиться
  • 1
    спасибо, upvoted, но ваш код возвращает массив с пустыми объектами (т. е. [{}, {}]). Я думаю, что мне нужно включить где-то await, но не мог понять, где – MyTitle 27 February 2017 в 17:13
  • 2
    Как выглядит функция service.getByValue? – helb 27 February 2017 в 17:19
  • 3
    он просто возвращает ES6 Promise – MyTitle 27 February 2017 в 19:03
  • 4
    Мне кажется, что OP ожидает массив id'ed объектов в качестве конечного результата, поэтому, в соответствии с этим, я думаю, вы, вероятно, захотите return await Promise.all(myArray.map ... для эквивалентности. – jib 27 February 2017 в 22:33
Другие вопросы по тегам:

Похожие вопросы: