javascript - 您如何同时映射生成器结果?

标签 javascript ecmascript-6

如何在生成器中同时映射异步调用的结果?

var generator = (function *() {
  var lotsOfThings = yield asyncTask.call(generator);

  var mappedResults = yield lotsOfThings.map(thing => {
    // fails with a syntax error unless you do a `for…of` loop, but also doesn’t run concurrently regardless
    return (yield asyncTask.call(generator, thing));
  });

  // then do something with mappedResults
})();

generator.next();

function asyncTask(…query) {
  somethingAsync(…query, (err, res) => this.next(res));
}

此外,即使在常规的 for...of 循环中,您也无法同时运行每个 asyncTaskyield 将导致每个任务之间暂停,本质上是发出同步 AJAX 请求。理想情况下,您希望它像使用 promises 一样工作,就像这个范例:

// these tasks will run concurrently (unlike the above example)
let promises = someThings.map(thing => {
  return new Promise((resolve, reject) => {
    somethingAsync((err, res) => {
      resolve(res);
    });
  });
});

Promise.all(promises).then(/* do stuff */);

promise 方法可能会因为所有嵌套而变得毛茸茸,但好处是异步任务可以并发运行……而生成器看起来不错,但循环任务不是并发的。有什么想法吗?

最佳答案

我尝试在没有第三方库的情况下勾勒出类似的东西:

// Async runner
function async(generator){
  var process = function(result){       
    if (result.done) {
      return;
    }
    (Array.isArray(result.value) ? Promise.all(result.value) : result.value).then(function(value){
      process(sequence.next(value));
    });
  };

  var sequence = generator();
  var next = sequence.next();
  process(next);
};

// Generator function
var generator = function* () {
  var list = yield getList();
  console.log(list); // outputs [1, 2, 3, 4, 5]

  var details = yield list.map(p => getDetails(p));    
  console.log(details); // outputs [11, 12, 13, 14, 15]
}

// Your async requests go here
function fakeAsync(f) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      f(resolve);
    }, 500);
  });
}

function getList() {
  return fakeAsync(function(resolve) {
    resolve([1, 2, 3, 4, 5]);                  
  });
}

function getDetails(i) {
  return fakeAsync(function(resolve) {
    resolve(i + 10);                  
  });
}

async(generator);

这是您想要实现的目标吗?

关于javascript - 您如何同时映射生成器结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32576115/

相关文章:

javascript - 如何使用目标空白在不同选项卡中打开网址

javascript - 获取文件名和父目录名的方法

javascript - 为什么 TypeScript 将 .default 添加到全局定义的导入中?

javascript - 延迟 "manual"将元素升级为定制的内置 Web 组件

javascript - ES6从变量解构

javascript - 日期验证 - 如何解决 Javascript 的自动更正日期问题?

javascript - onClientClick 返回 true 时不会触发 OnClick 事件

javascript - Angular JS,控制台中的验证错误

javascript - 避免嵌套条件中的重复

javascript - Jasmine 中 beforeAll() 的目的是什么?