使用生成器暂停直到承诺解决

Jef*_*eff 5 javascript generator node.js ecmascript-6 es6-promise

我在 node.js 中有一个批处理作业: 将文件复制到目录中,对文件进行分析,然后删除文件。

我想迭代一系列作业并使用生成器暂停执行,直到批处理作业完成,然后再开始另一个作业。这是我到目前为止所拥有的:

const cars = ["toyota", "honda", "acura"];

function copyFilesAndRunAnalysis(car) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() { // simulate some delay
      resolve(); // control should return to generator here
    }, 1000);
  });
}

function* doCar(car) {
  yield copyFilesAndRunAnalysis(car);
}

// BEGIN HERE
console.log('start here');
carBatch = doCar(cars[0]);
carBatch.next(); // confusion here!!!
carBatch.next(); // should this all be in a forEach loop?
Run Code Online (Sandbox Code Playgroud)

我想做的是有一个 forEach 循环每辆车,完成该copyFilesAndRunAnalysis方法中的所有相应工作 - 暂停直到Promise.resolve()然后继续到下一辆。尝试 forEach 根本不会让任何东西运行。

gue*_*314 4

您不使用.valueat jsat 问题。由 产生的对象的将从.value中返回,其中可以链接到,可以用于递归调用,直到没有项目保留在数组的原始或副本中。next()GeneratorPromisecopyFilesAndRunAnalysis.then().next().value()Array.prototype.shift()doCarcars

const cars = ["toyota", "honda", "acura"];
let carsCopy = cars.slice(0);

function copyFilesAndRunAnalysis(car) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() { // simulate some delay
      resolve(car); // control should return to generator here
    }, 1000);
  })
}

function* doCar(cars) {
  yield copyFilesAndRunAnalysis(cars);
}

// BEGIN HERE
console.log("start here");
carBatch = doCar(carsCopy.shift());
carBatch.next().value.then(function re(data) {
  console.log(data);
  return carsCopy.length 
         ? doCar(carsCopy.shift()).next().value.then(re) 
         : "complete"
})
.then(function(complete) {
  console.log(complete); 
})
Run Code Online (Sandbox Code Playgroud)

注意,利用 、 递归可以实现相同的过程Promise;不使用Generator函数。

const cars = ["toyota", "honda", "acura"];
let carsCopy = cars.slice(0);

function copyFilesAndRunAnalysis(car) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() { // simulate some delay
      resolve(car); // control should return to generator here
    }, 1000);
  })
}

// BEGIN HERE
console.log("start here");
carBatch = copyFilesAndRunAnalysis(carsCopy.shift());
carBatch.then(function re(data) {
  console.log(data);
  return carsCopy.length 
         ? copyFilesAndRunAnalysis(carsCopy.shift()).then(re) 
         : "complete"
})
// do stuff when all items within `cars` have been 
// processed through `copyFilesAndRunAnalysis`
.then(function(complete) {
  console.log(complete); 
})
Run Code Online (Sandbox Code Playgroud)