【问题标题】:Why does my recursive function with promises only wait once?为什么我的带有承诺的递归函数只等待一次?
【发布时间】:2019-01-10 17:33:09
【问题描述】:

我正在尝试可视化“河内塔”问题,并尝试使用 Promise 使函数等待一张光盘的运动被动画化(我使用 setTimeout 模拟),然后再继续解决问题。此测试代码计算正确的动作,但只等待动画一次,然后立即吐出其余的:

    var A = "rod A";
    var B = "rod B";
    var C = "rod C";

    solve(3,A,C,B);

    function solve (n,source,target,spare) {
        var promise = new Promise(function(resolve,reject){
            if (n==1) {
                setTimeout(function(){
                    console.log("move a disc from "+source+" to "+target);
                    resolve();
                },1000);
            }
            else {
                        solve(n-1,source,spare,target)
                .then(  solve( 1 ,source,target      )  )
                .then(  solve(n-1,spare,target,source)  )
                .then(  resolve()                       );
            }
        });
        return promise;
    }

对于不知道问题的人,我稍微简化了代码,本质上目标是打印“移动”七次,每次延迟一秒:

    solveTest(3);

    function solveTest (n) {
        var promise = new Promise(function(resolve,reject){
            if (n==1) {
                setTimeout(function(){
                    console.log("move");
                    resolve();
                },1000);
            }
            else {
                        solveTest(n-1)
                .then(  solveTest( 1 )  )
                .then(  solveTest(n-1)  )
                .then(  resolve()       );
            }
        });
        return promise;
    }

【问题讨论】:

  • .then(resolve()) 不会像您认为的那样做,您的任何其他函数调用也不会作为.then() 的参数

标签: javascript promise towers-of-hanoi


【解决方案1】:

问题是您立即调用所有调用,然后将它们的返回值作为参数传递给.then()。您需要做的是将函数传递给 .then() 来调用它们:

function sleep (ms) {
  return new Promise(function (resolve) {
    setTimeout(resolve, ms)
  })
}

function solve (n, source, target, spare) {
  if (n === 1) {
    return sleep(1000).then(function () {
      console.log('move a disc from ' + source + ' to ' + target)
    })
  } else {
    return solve(n - 1, source, spare, target).then(function () {
      return solve(1, source, target, spare)
    }).then(function () {
      return solve(n - 1, spare, target, source)
    })
  }
}

solve(3, 'rod A', 'rod B', 'rod C')

但您可以使用asyncawait 使其更易于阅读:

const sleep = ms => new Promise(resolve => { setTimeout(resolve, ms) })

async function solve (n, source, target, spare) {
  if (n === 1) {
    await sleep(1000)
    console.log(`move a disc from ${source} to ${target}`)
  } else {
    await solve(n - 1, source, spare, target)
    await solve(1, source, target, spare)
    await solve(n - 1, spare, target, source)
  }
}

solve(3, 'rod A', 'rod B', 'rod C')

【讨论】:

    猜你喜欢
    • 2019-04-29
    • 2022-01-09
    • 2018-07-31
    • 2015-12-05
    • 1970-01-01
    • 2017-05-09
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多