【问题标题】:How can I call series of Promise functions?如何调用一系列 Promise 函数?
【发布时间】:2018-09-23 04:42:33
【问题描述】:

要求是在移动到下一个调用之前完成当前函数:

var current_data = something;
Run(current_data).then((data1) => {
    Run(data1).then(data2 => {
        Run(data2).then(data3 => {
            // and so on
        })
    })
});

只有在我确切地知道我想要获取多少数据的情况下才能使用上面的示例。

【问题讨论】:

    标签: javascript function asynchronous async-await promise


    【解决方案1】:

    为了使嵌套的 Promise 成为 Promise 链的一部分,您需要返回嵌套的 Promise。

    Run(current_data).then((data1) => {
        return Run(data1).then(data2 => {
            return Run(data2).then .....
        });
    });
    

    【讨论】:

    • return 和 not 有什么区别?
    • 如果你没有在then回调中添加return,函数会创建promise并返回undefined。但是,如果您添加 return 它会返回承诺并将该承诺作为链的一部分。
    【解决方案2】:

    我会假设您的数据是分页的,并且您不知道有多少页,因此您可以在 async 函数中使用带有 await 的 while 循环,如下所示:

    (async function() {
      var currentData = someInitialData;
      // loop will break after you've processed all the data
      while (currentData.hasMoreData()) {
        // get next bunch of data & set it as current
        currentData = await Run(currentData);
        // do some processing here or whatever
      }
    })();
    

    【讨论】:

    • 如果我的回答解决了您的问题,请点击我的回答旁边的灰色复选标记接受,谢谢!
    【解决方案3】:

    您可以使用 async-await 使代码更具可读性。

    async function getData(current_data){
      let data1 = await Run(current_data)
      let data2 = await Run(data1);
      let result = await Run(data2);
      return result;  
    }
    

    调用getData函数

    getData(data)
     .then(response => console.log(response))
     .catch(error =>  console.log(error));
    

    【讨论】:

      【解决方案4】:

      尽量避免嵌套的承诺。如果你需要调用一系列依赖于先前调用的响应的承诺,那么你应该像下面这样链接 then -

      const promise1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('foo');
        }, 1000);
      });
      
      promise1.then((response) => {
      
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(response + ' b');
          }, 1000);
        });
      
      }).then((responseB) => {
      
      
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(responseB + ' c');
          }, 1000);
        });
      
      }).then((responseC) => {
      
        console.log(responseC); // 'foo b c'
      })

      如果您的代码可以支持 async-await,那么 Mohammed Ashfaq 的建议就是一个替代方案。

      【讨论】:

        【解决方案5】:

        如果您一遍又一遍地执行相同的函数,但在不同的数据上,我会创建一个返回 Promise 的递归函数。

        我只是在下面使用一个数字数组查看我的示例,您可以将其编辑为您当前的情况。

        var current_data = [1,2,4,5,6]
        
        function Run(data){
          if(data.length === 0)
            return Promise.resolve(data);
          
          return new Promise((resolve, reject)=>{
            //your async operation
            //wait one second before resolving
            setTimeout(()=>{
              data.pop()
              console.log(data)
              resolve(data)
            },1000)
          })
          .then((results)=>{
            return Run(results)
          })
           
        }
        
        Run(current_data)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-10-15
          • 1970-01-01
          • 2016-05-26
          • 1970-01-01
          • 1970-01-01
          • 2018-05-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多