等同于等待多个异步函数的承诺链是什么?
What's the promise chaining equivalent of awaiting multiple async functions?
我正在研究 promsies 和 async/await 的用法。
我编写了以下代码,它执行以下操作:
- 它获取一些数据库的数据(使用Knex.js),
- 处理该数据,
- 将处理的数据分配到指定的属性。
这 3 个步骤进行了多次(在下面的代码中,进行了两次),并且总是 await
ed:
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
的承诺链等价物,这就是我想出的:
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;
}
但这并不完全有效。发生的事情是,在第一个 then
return 之后, run
内的 await
结束等待,这导致 run
到 return - 并且然后才执行第二个 then
。
如何使 promise-chaining 版本像 multiple-await 版本一样工作?
(请随时指出我对 promises/async-await 的任何误解)
knex.select().then()
return 是一个承诺,所以你不需要将它包装在另一个承诺中,你只需要设置 then()
和 [=23= 的链] 整个东西。结果将是 getData
return 上次的承诺。您可以 return 从 then()
中获得您想要的值,这将使调用者可以使用它。例如:
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 }));
我正在研究 promsies 和 async/await 的用法。
我编写了以下代码,它执行以下操作:
- 它获取一些数据库的数据(使用Knex.js),
- 处理该数据,
- 将处理的数据分配到指定的属性。
这 3 个步骤进行了多次(在下面的代码中,进行了两次),并且总是 await
ed:
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
的承诺链等价物,这就是我想出的:
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;
}
但这并不完全有效。发生的事情是,在第一个 then
return 之后, run
内的 await
结束等待,这导致 run
到 return - 并且然后才执行第二个 then
。
如何使 promise-chaining 版本像 multiple-await 版本一样工作?
(请随时指出我对 promises/async-await 的任何误解)
knex.select().then()
return 是一个承诺,所以你不需要将它包装在另一个承诺中,你只需要设置 then()
和 [=23= 的链] 整个东西。结果将是 getData
return 上次的承诺。您可以 return 从 then()
中获得您想要的值,这将使调用者可以使用它。例如:
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 }));