Ответ 2
Нет, вы не можете уступить от обратного вызова (технически это не "внутренняя функция", что означает что-то еще). Очевидно, нет способа вызвать forEach
с эквивалентом *
или, если сам обратный вызов является генератором, сообщить forEach
для вызова обратного вызова с помощью yield *
.
Один из вариантов - написать функцию forEachGen
следующим образом:
function *forEachGen(array, fn) { for (var i of array) yield *fn(i); }
по существу перемещая for-loop в forEachGen
. Определение небольшого генератора выборок как
function *yieldSelf(item) { yield item; }
forEachGen
будет использоваться как
yield *forEachGen(array, yieldSelf);
Это предполагает, что обратный вызов является самим генератором, поскольку вы, кажется, подразумеваете, что хотите в своем примере. Если обратный вызов был ROF (обычная старая функция), например
function returnSelf(item) { return item; }
Тогда это будет
function *forEachGen(array, fn) { for (var i of array) yield fn(i); }
используется как
yield *forEachGen(array, returnSelf);
Если вы не возражаете добавить это в прототип массива, то
Object.defineProperty(Array.prototype, 'forEachGen', { value :
function *(fn) { for (i of this) yield fn(i); }
});
то do
yield *array.forEachGen(yieldSelf)
Вам может быть интересен http://fitzgen.github.io/wu.js/, который определяет оболочку для генераторов с такими методами, как forEach
на обертке.
async
/await
С помощью await
вы сможете сделать следующее.
Определите тривиальный обратный вызов, который просто возвращает обещание для себя.
async function returnSelf(item) { return await item; }
forEachAsync
отображает входной массив в массив promises и использует await *
для создания и возврата обещания для всех индивидуальных promises, которые будут готовы.
async function forEachAsync(values, fn) {
return await *values.map(returnSelf);
}
Мы можем рассматривать результат как обычное обещание и распечатывать его в then
:
forEachAsync([1,2,3], returnSelf) .
then(result => console.log(result);
или используйте небольшую оболочку асинхронного типа IIFE, чтобы дождаться результата, а затем распечатайте его:
(async function() {
console.log(await forEachAsync([1,2,3], returnSelf));
})();
Протестировано с помощью
babel-node --experimental test.js