Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么.then()在promise实际解决之前就被解雇了?_Javascript_Es6 Promise - Fatal编程技术网

Javascript 为什么.then()在promise实际解决之前就被解雇了?

Javascript 为什么.then()在promise实际解决之前就被解雇了?,javascript,es6-promise,Javascript,Es6 Promise,我正在尝试从异步任务返回承诺,以便使用.then()调用使它们同步。不幸的是,我正在经历一些真正奇怪的行为。基本上,第三个then()在第二个问题解决之前执行。有人能解释一下发生了什么事吗?这是我的密码: function runReleaseLoop() { console.log('Starting release loop'); const themes = ['blue', 'red']; return new Promise(resolve => { buil

我正在尝试从异步任务返回承诺,以便使用.then()调用使它们同步。不幸的是,我正在经历一些真正奇怪的行为。基本上,第三个then()在第二个问题解决之前执行。有人能解释一下发生了什么事吗?这是我的密码:

function runReleaseLoop() {
  console.log('Starting release loop');
  const themes = ['blue', 'red'];
  return new Promise(resolve => {
    buildReleases(themes, resolve);
  })
}

function buildReleases(themes, onComplete) {
  console.log(themes);
  if (themes.length === 0) {
    onComplete();
  } else {
    const theme = themes.pop();
    Promise.resolve()
      .then(setTheme(theme))
      .then(someDelayedTask(theme))
      .then(buildReleases(themes, onComplete));
  }
}

function setTheme(theme) {
  return new Promise(resolve => {
    console.log(`Setting theme to ${theme}`);
    resolve();
  });
}

function someDelayedTask(theme) {
  console.log(`Starting delayed task related to ${theme}`);
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`Finished delayed task related to ${theme}`);
      resolve();
    }, 3000)
  });
}

// Run the process
runReleaseLoop()
  .then(() => {
    console.log('Release loop finished')
  });
以下是我的控制台输出:

"Starting release loop"
["blue", "red"]
"Setting theme to red"
"Starting delayed task related to red"
["blue"]
"Setting theme to blue"
"Starting delayed task related to blue"
[]
"Release loop finished"
"Finished delayed task related to red"
"Finished delayed task related to blue"

您正在同步调用这些函数(
setTheme
someDelayedTask
,以及
buildReleases
),然后将它们的返回值(承诺)传递到
然后
,而不是将函数本身传递到:

Promise.resolve()
  .then(setTheme(theme))
  .then(someDelayedTask(theme))
  .then(buildReleases(themes, onComplete));
这里有一个解决方案:

Promise.resolve()
  .then(_ => setTheme(theme))
  .then(_ => someDelayedTask(theme))
  .then(_ => buildReleases(themes, onComplete));
以下是进行上述更改后的代码输出:

Starting release loop
[ 'blue', 'red' ]
Setting theme to red
Starting delayed task related to red
Finished delayed task related to red
[ 'blue' ]
Setting theme to blue
Starting delayed task related to blue
Finished delayed task related to blue
[]
Release loop finished

第一个问题是,你把承诺和回访混为一谈。第二个是一次性调用所有函数
setTheme、someDelayedTask、buildReleases

function runReleaseLoop() {
  console.log('Starting release loop');
  const themes = ['blue', 'red'];
  return buildReleases(themes);
}

function buildReleases(themes) {
  console.log(themes);
  if (themes.length === 0) {
    return Promise.resolve();
  }

  const theme = themes.pop();
  return setTheme(theme)
    .then(() => someDelayedTask(theme))
    .then(() => buildReleases(themes));
}

function setTheme(theme) {
  console.log(`Setting theme to ${theme}`);
}

function someDelayedTask(theme) {
  console.log(`Starting delayed task related to ${theme}`);
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`Finished delayed task related to ${theme}`);
      resolve();
    }, 3000)
  });
}

// Run the process
runReleaseLoop()
  .then(() => console.log('Release loop finished'));

因此,对于接受参数的函数,我需要返回一个返回承诺的函数?是的,正确(oops删除了第一条注释lol),但是您还需要按照返回的承诺执行操作,等等。您还可以执行以下操作:promise.resolve().then(setTheme)。然后(someDelayedTask)。然后(buildReleases);