【问题标题】:How to wait for promise to finish before function returns如何在函数返回之前等待 promise 完成
【发布时间】:2022-03-15 08:13:01
【问题描述】:

基本承诺问题:

console.log('Promise START');

function makeFullJSON(time) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, time, [time]);
  })
}

var p1 = makeFullJSON(1000);
var p2 = makeFullJSON(500);
var p3 = makeFullJSON(750);

p1.then(array => {
  console.log('Promise 1 complete', array);
});

p2.then(array => {
  console.log('Promise 2 complete', array);
});

p3.then(array => {
  console.log('Promise 3 complete', array);
});

Promise.all([p1, p2, p3]).then(arrayOfAllResolvedValues => {
  console.log('Array of resolved values:', arrayOfAllResolvedValues);
});

console.log('Promise END');

代码输出为:

Promise START
Promise END
Promise 2 complete [ 500 ]
Promise 3 complete [ 750 ]
Promise 1 complete [ 1000 ]
Array of resolved values: [ [ 1000 ], [ 500 ], [ 750 ] ]

你如何重写代码,输出如下:

Promise START
Promise 2 complete [ 500 ]
Promise 3 complete [ 750 ]
Promise 1 complete [ 1000 ]
Array of resolved values: [ [ 1000 ], [ 500 ], [ 750 ] ]
Promise END

【问题讨论】:

  • 听起来像是stackoverflow.com/q/14220321/497418的副本。
  • 只需将 Promise END console.log 放在 resolved values 旁边吗?
  • Promise.all([p1, p2, p3]).then(() => console.log('Promise END'))
  • 您永远不能让 Javascript 中的解释器“等待”任何异步操作。相反,你做你在任何单线程、事件驱动的系统中总是做的事情——你注册一个回调来在操作完成时得到通知,然后你在那个回调中执行你的工作。您不会在 Javascript 中“等待”。
  • 谢谢大家。我同意回拨通知。这似乎是目前唯一的方法(直到我开始使用异步等待模式)。

标签: javascript promise


【解决方案1】:

完成后您希望发生的任何事情都在您传递给的箭头函数中。

    console.log('Promise START')
    
    function makeFullJSON(time) {
       return new Promise((resolve, reject) => {
       setTimeout(resolve, time, [time])
    })}
    
    var p1 = makeFullJSON(1000)
    var p2 = makeFullJSON(500)
    var p3 = makeFullJSON(750)
    
    p1.then(array => {
        console.log('Promise 1 complete', array)})
    
    p2.then(array => {
        console.log('Promise 2 complete', array)})
    
    p3.then(array => {
        console.log('Promise 3 complete', array)})
    
    Promise.all([p1, p2, p3]).then(arrayOfAllResolvedValues => {
        console.log('Array of resolved values:', arrayOfAllResolvedValues)
    
        console.log('Promise END')
    })

为了放弃立即执行程序,并开始编写只有在所有 3 个 Promise 解决后才会发生的代码,因为这听起来像是你想要发生的那样,那么我建议在你的代码下直接创建一个新函数,以包含代码您希望在解决后发生,并传递该函数,例如:Promise.all([p1, p2, p3]).then(newFunctionName)。以这种方式可视化它可能更容易,至少在您习惯于思考它是如何精确工作的之前。

【讨论】:

  • 这个答案的第一句话说明了一切。谢谢肯特。你拯救了我的一天。
【解决方案2】:

首先修复语法错误。然后将console.log移到整个流程结束的地方:

console.log('Promise START');

function makeFullJSON(time) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, time, [time]);
  })}

var p1 = makeFullJSON(1000);
var p2 = makeFullJSON(500);
var p3 = makeFullJSON(750);

p1.then(array => {
  console.log('Promise 1 complete', array);});

p2.then(array => {
  console.log('Promise 2 complete', array);});  // fixed syntax error here

p3.then(array => {
  console.log('Promise 3 complete', array);});

Promise.all([p1, p2, p3]).then(arrayOfAllResolvedValues => {
  console.log('Array of resolved values:', arrayOfAllResolvedValues);
  console.log('Promise END');
});

【讨论】:

  • console.log('Promise 2 complete', array););
  • 啊,没发现。在相应的位置用评论指出这些事情总是好的
  • 好建议。完成
【解决方案3】:

如果放置 console.log('Promise END') 的明显答案不会让您的船浮起来,为什么不这样做呢?

//didnt change anything at all above here
Promise.all([p1, p2, p3]).then(arrayOfAllResolvedValues => {
    console.log('Array of resolved values:', arrayOfAllResolvedValues);
}).then(() => {
    console.log('Promise END');
});

如果您想在所有承诺都实现后对操作进行排序,您必须使用then() 进行排序,就像您在打印数组值时所做的那样

【讨论】:

    【解决方案4】:

    使用async/await:

    (async () => {
      console.log('Promise START');
    
      function makeFullJSON(time) {
        return new Promise((resolve, reject) => {
        setTimeout(resolve, time, [time]); 
      })}
    
      var p1 = makeFullJSON(1000);
      var p2 = makeFullJSON(500);
      var p3 = makeFullJSON(750);
    
      p1.then(array => {
        console.log('Promise 1 complete', array);});
    
      p2.then(array => {
        console.log('Promise 2 complete', array);});
    
      p3.then(array => {
        console.log('Promise 3 complete', array);});
    
      console.log('Array of resolved values:', await Promise.all([p1, p2, p3]));
    
      console.log('Promise END');
    })();

    【讨论】:

    • 感谢大家的所有 cmets。问题是,如果上面的代码在另一个函数 B 调用的函数 A 中怎么办。函数 B 需要在调用 A 之后完成所有的承诺,才能继续。这类似于等待模式。我知道解决这个问题的唯一方法(不等待)是将回调传递给函数 A 并在 Promise.all 中调用它(如建议的那样)。我说的对吗?
    • @S.Vaghar 让函数 A 从 Promise.all 返回承诺?
    猜你喜欢
    • 2015-03-01
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-17
    • 2019-03-03
    相关资源
    最近更新 更多