Javascript 等待多个异步函数的承诺链等价于什么?

Javascript 等待多个异步函数的承诺链等价于什么?,javascript,ecmascript-6,promise,async-await,chaining,Javascript,Ecmascript 6,Promise,Async Await,Chaining,我正在研究promsies和async/await的用法 我编写了以下代码,它执行以下操作: 它使用Knex.js获取一些数据库数据, 处理这些数据, 将处理的数据分配到指定的属性中。 这3个步骤在以下代码中执行了多次,执行了两次,并且一直在等待: 现在,我正在尝试编写与getData等效的承诺链,这就是我想到的: async function getData() { let handledData = {}; let promise = new Promise(function

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

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

它使用Knex.js获取一些数据库数据, 处理这些数据, 将处理的数据分配到指定的属性中。 这3个步骤在以下代码中执行了多次,执行了两次,并且一直在等待:

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

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;
}
但这不太管用。发生的情况是,在第一个运行返回后,内部的wait运行结束其等待,这导致运行返回,只有在第二个运行返回后才执行

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

请随意指出我对承诺/async await

knex.select.的任何误解,然后返回一个承诺,因此您不需要将其包装在另一个承诺中,您只需要设置一个承诺链并返回整个承诺。结果将是getData返回上一个数据库的承诺。您可以从调用方可以使用的值中返回所需的值。例如:

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是同步的,因此您不需要将其设置为异步函数。

knex.select.然后返回一个承诺,因此您不需要将其封装在另一个承诺中,只需设置一个承诺链并返回整个承诺。结果将是getData返回上一个数据库的承诺。您可以从调用方可以使用的值中返回所需的值。例如:

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函数是同步的,因此您不需要将其设置为异步函数。

如果可能,我建议使用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 }));

如果可能的话,我建议使用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 }));

您需要使用等待请求还是顺序请求?最好使用Promise.all并行请求,而不是串行请求requests@CertainPerformance,这是个好主意,我会的。您需要使用等待请求还是顺序请求?最好使用Promise.all并行请求,而不是串行请求requests@CertainPerformance,好主意,我会的,谢谢。2个问题:我不会立即运行return,而不是在我的原始代码上等待它?2我使用包装使代码结构化,这样每个代码都包含一个查询和处理程序,即一个then和一个catch。您的建议使它们交替进行:一个进行查询,另一个处理其结果,以此类推,考虑一种情况,其中有两个以上的查询。您不觉得它没有那么结构化/干净吗?@HeyJude是的,run将立即启动-然后中的代码将等待查询完成。如果要调用run,您应该返回getData。然后这将返回一个承诺,就像异步函数一样。这里的结构对于每个查询仍然有一个then。第二个select确实使用了从第一个select返回的任何内容,它只是被链接起来,所以它可以像async`版本一样按顺序运行。我个人更喜欢异步版本,但可能会尝试同时运行两个查询,因为它们互不依赖。谢谢。2个问题:我不会立即运行return,而不是在我的原始代码上等待它?2我使用包装使代码结构化,这样每个代码都包含一个查询和处理程序,即一个then和一个catch。您的建议使它们交替进行:一个进行查询,另一个处理其结果,以此类推,考虑一种情况,其中有两个以上的查询。您不觉得它没有那么结构化/干净吗?@HeyJude是的,run将立即启动-然后中的代码将等待查询完成。如果要调用run,您应该返回getData。然后这将返回一个承诺,就像异步函数一样。这里的结构对于每个查询仍然有一个then。第二个select确实使用了从第一个select返回的任何内容,它只是被链接起来,所以它可以像async`版本一样按顺序运行。我个人更喜欢异步版本,但可能会尝试同时运行两个查询,因为它们互不依赖。我喜欢这样做,而不是按顺序运行查询,因为它们互不依赖。我喜欢这样做,而不是按顺序运行查询,因为它们互不依赖。