当前位置: 首页 > 知识库问答 >
问题:

等待多个异步函数的promise链等效是什么?

令狐珂
2023-03-14

我正在研究promsies和async/await的用法。

我编写了以下代码,它执行以下操作:

  1. 它获取一些数据库数据(使用Knex.js),
  2. 处理该数据,
  3. 将处理的数据分配到指定的属性中

这3个步骤执行了多次(在下面的代码中,执行了两次),并且始终等待执行:

async function run() {
   return await getData();
}
async function getData() {
    let handledData = {};
    handledData.res1 = await knex.select('column1').from('table1').where('column1', '1')
                                 .then(data => handleData(data))
                                 .catch(handleError);
    handledData.res2 = await knex.select('column1').from('table1').where('column1', '2')
                                 .then(data => handleData(data, handledData))
                                 .catch(handleError);
    return handledData;
}
async function handleData(data) {
    let res = [];
    data.forEach(item => {
        res.push(item.column1);
    });
    return res; 
}
function handleError (error) {
    console.log(error);
}

现在,我正在尝试编写与getData等效的promise链,这就是我想到的:

async function getData() {
    let handledData = {};
    let promise = new Promise(function(resolve, error){ resolve(); });
    promise
    .then(function () {
        return knex.select('column1').from('table1').where('column1', '1')
                    .then(data => handleData(data))
                    .catch(handleError);
    })
    .then(function(handled){
        handledData.res1 = handled;
        return knex.select('column1').from('table1').where('column1', '2')
                    .then(data => handleData(data))
                    .catch(handleError);
    })
    .then(function(handled){
        handledData.res2 = handled;
        return handledData;
    })
    .catch(handleError);
    return promise;
}

但这不太管用。发生的是,在第一个然后返回之后,run中的wait结束了它的等待,这导致run返回-并且只有在第二个然后被执行。

如何使promise链接版本像多重等待版本那样工作?

(请随时指出我对promise/异步等待的任何误解)

共有2个答案

卓云
2023-03-14

knex.select()。然后()返回一个promise,所以你不需要用另一个promise包装它,你只需要设置然后()s的链并返回整个东西。结果将是getData返回上次的promise。您可以从该然后()返回您想要的值,这将使它对调用方可用。例如:

function run() {
    getData()
    .then(handledData => console.log(handledData) /* do something with data */)
}

function getData() {
    let handledData = {};
    // need to return this promise to callers can access it
    return knex.select('column1').from('table1').where('column1', '1')
    .then(data => handledData.res1 = handleData(data))
    .then(() => knex.select('column1').from('table1').where('column1', '2'))
    .then(data => {
        handledData.res2 = handleData(data)
        return handledData
    })
    .catch(handleError);
}

您还可以将其设置为将handledData对象传递给链,但在这种情况下不需要这样做。

函数handleData()是同步的,因此不需要将其设为异步函数。

董桐
2023-03-14

如果可能的话,我建议使用Promise.all,这将使您的脚本运行得更快,并且使逻辑更清晰:

const getData = Promise.all([
  knex.select('column1').from('table1').where('column1', '1')
    // Simply pass the function name as a parameter to the `.then`:
    .then(handleData)
    .catch(handleError),
  knex.select('column1').from('table1').where('column1', '2')
    .then(handleData)
    .catch(handleError)
])
  .then(([res1, res1]) => ({ res1, res2 }));
 类似资料:
  • 我试图利用es7异步功能,即。 在这里,所有promise*函数都进行ajax调用,并返回或如果ajax响应满足传递的参数,我相信我不能连续使用3个等待,因此需要一种方法来等待所有这些调用以某种方式返回它们的值。

  • 我正试图将图像上传到firebase存储,但调用该函数时,未执行wait以获取url。我错过了什么? 看看这个其他主题,我发现问题可能是“然后”,但我如何设置代码以等待url? 异步/等待/然后飞镖/颤振 谢谢

  • 我在中写了这段代码 然后我尝试在另一个文件中使用它 我得到一个错误 “等待仅在异步函数中有效” 问题是什么?

  • 问题内容: 我是一名普通的C#开发人员,但有时我会使用Java开发应用程序。我想知道是否有Java等效于C#async / await?简单来说,java相当于什么: 问题答案: 不,在Java中-甚至在v5之前的C#中,都没有等效的异步/等待方式。 在后台构建状态机是一项相当复杂的语言功能。 Java中对异步/并发的 语言 支持相对较少,但是该软件包包含许多与此相关的有用 类 。(不完全等同于任

  • 我正在努力学习如何正确使用async Wait,但我对它有点共同的想法。 在片段中,我试图构建一个对象数组,其中包含我需要的关于我在组件中上传的文件的信息。问题是this.fileInfo中的对象并没有完全等待返回编码图像的promise,而是在我console.logthis.fileInfo时返回此输出: 如您所见,关键图像是一个值未定义的ZoneAwarePromise。你能帮我修一下吗?

  • Ubuntu 20 节点12.18。4 npm6.14。6 续集6.3。5. 我遵循官方指南,现在感到很困惑 成功配置Sequelize并连接后,我尝试运行(来自官方文档) 它抛出。 在正式开始页面https://sequelize.org/master/manual/getting-started.html,它清楚地指出: Sequelize提供的大多数方法都是异步的,因此会返回Promises