等待多个异步功能的诺言链相当于什么?

时间:2018-07-24 22:44:56

标签: javascript ecmascript-6 promise async-await chaining

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

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

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

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

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-chaining,这就是我想出的:

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返回之后,await中的run结束了等待,这导致run返回-仅第二个then返回被执行。

如何使诺言链接版本像多次等待版本那样工作?

(并且,请随时指出我对promises / async-await所做的任何误解)

2 个答案:

答案 0 :(得分:2)

如果可能,我建议改用total = 0 limit = 10 for (var i = 0; i < limit; total += i) { // log the numbers 0 through i console.log(i) } ,除了使逻辑更清晰之外,它还可以使脚本运行得更快:

Promise.all

答案 1 :(得分:1)

if (retLabels.Code == "OK" || ediDemo) { asnGraph.ASN.Current = asn; PXNoteAttribute.AttachFile(asn, retLabels.Labels, ???? PX.SM.FileInfo ); } 返回一个Promise,因此您无需将其包装在另一个Promise中,只需建立knex.select().then()的链并返回整个东西。结果将是then()返回最后一个承诺。您可以从getData返回所需的值,这将使调用者可以使用它。例如:

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是同步的,因此您无需使其成为异步函数。