简体   繁体   English

在异步代码的for循环完成后,如何解决此承诺?

[英]How do I resolve this promise after a for-loop of asynchronous code finishes?

Can't seem to figure out how to make this work without the setTimeout. 似乎无法弄清楚如何在没有setTimeout的情况下进行这项工作。 I want to console log my map only after the asynchronous PostgreSQL stuff is finished and the map contains all the key/value pairs it should. 我只想在异步PostgreSQL内容完成并且该映射包含它应该包含的所有键/值对之后,控制台记录我的映射。

const map = new Map();
pool.query(`SELECT * FROM trips WHERE destination = $1 AND begin_time >= $2 AND begin_time < $3 ORDER BY begin_time`, ['BROWNSVILLE ROCKAWAY AV', '2018-07-18 00:00-04:00', '2018-07-19 00:00-04:00'])
.then(res => {
    return new Promise((resolve, reject) => {
        const { rows } = res;
        resolve(rows);
    });
})
.then(res1 => {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < res1.length; i++) {
            if (res1[i + 1]) {
                pool.query(`SELECT * FROM get_hwtable($1, $2)`, [res1[i].trip_id, res1[i + 1].trip_id]).then(res => {
                    const { rows: hwRows } = res;
                    map.set([res1[i].trip_id, res1[i + 1].trip_id], hwRows);
                }).catch(e => console.log('20', e));
            }
        }
        setTimeout(() => {
            resolve(map);
        }, 8000);
    });
})
.catch(e => console.log('25', e))
.finally(function () {
    console.log(map);
});

You can simply use Promise.all on an array of promises returned by pool.query 你可以简单地使用Promise.all由归国承诺阵列上pool.query

const map = new Map();
pool.query(`SELECT * FROM trips WHERE destination = $1 AND begin_time >= $2 AND begin_time < $3 ORDER BY begin_time`, ['BROWNSVILLE ROCKAWAY AV', '2018-07-18 00:00-04:00', '2018-07-19 00:00-04:00'])
.then(({rows}) => rows)
.then(res1 => Promise.all(res1.map((r, i) => {
    if (res1[i + 1]) {
        return pool.query(`SELECT * FROM get_hwtable($1, $2)`, [r.trip_id, res1[i + 1].trip_id])
        .then(res => {
            const { rows: hwRows } = res;
            map.set([res1[i].trip_id, res1[i + 1].trip_id], hwRows);
        }).catch(e => console.log('20', e))
    }                                 
})))
.catch(e => console.log('25', e))
.finally(function () {
    console.log(map);
});
  1. there are unnecessary constructs in your code. 您的代码中有不必要的构造。 In first then( res => {..} ) , there is no need to return a Promise . 首先then( res => {..} ) ,不需要返回Promise You can do 你可以做

``` ```

pool.query().then(res => {
    const {rows} = res;
    return rows;
}.then ....

``` ```

  1. If you are already using async you should use await and use this for the whole code block. 如果已经在使用async ,则应该使用await并将其用于整个代码块。 Could write a promisified timeout function too. 也可以编写一个承诺的超时函数。

``` ```

///returns a promise that resolves after `duration`
function timeoutPromise(duration) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, duration)
  })
}

async function doSomething() {
  const res = await pool.query()
  const {rows} = res;
  for (...) {
    let hwRows = await pool.query(`SELECT * FROM get_hwtable($1, $2)`, [res1[i].trip_id, res1[i + 1].trip_id]);
    map...
  }
  await timeoutPromise(5000)
}

doSomething()

``` ```

  1. Of course the above might make the user wait too long because the asynchronous operations ( let hwRows = await pool.query() ) will be executed one after another. 当然,以上内容可能会使用户等待太久,因为异步操作( let hwRows = await pool.query() )将一次又一次地执行。 use Array.map to return an array of Promise and then use Promise.all([Promise]) to get the values. 使用Array.map返回Promise数组,然后使用Promise.all([Promise])获取值。

``` ```

async function doSomething() {
  const res = await pool.query()
  const {rows} = res;
  let hwRowsPromises = rows.map((row) => {
    // ...
    // return the promise
    return pool.query(`SELECT * FROM get_hwtable($1, $2)`, [res1[i].trip_id, res1[i + 1].trip_id])
  })
  let hwRowsResults = Promise.all(hwRowsPromises)
  await timeoutPromise(5000)
}

``` 4. Promise.all resolves the values resolved by promises in an array, so you can use convenience like flatten to flatten the array. ```4. Promise.all解析数组中由Promise.all解析的值,因此您可以使用诸如flattenPromise.all数组的便利。

``` ```

_.flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]

``` ```

References 参考文献

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何在for循环后直到for循环完成其交互之前不运行代码? - How do I get the code after the for-loop to not run until the for-loop has completed its interations? 如何在异步 for 循环后调用 function? - How to call a function after an asynchronous for-loop? for循环完成后如何在Javascript中调用函数? - How to call a function in Javascript after a for-loop finishes? 解决在forEach循环完成之前发生的承诺 - Resolve of promise happening before forEach loop finishes 如何在Promise中处理异步代码? - How do I handle asynchronous code within a promise? 在node.js中的for循环之后完成多个writeFile函数时解析promise - Resolve promise when multiple writeFile functions finished after for-loop in node.js 在node.js中完成for循环后的回调 - Callback after for-loop finishes in node.js 如果库吞没所有异常,我如何调试我的异步,基于承诺的代码? - How do I debug my asynchronous, promise based code if the library is swallowing all the exceptions? TweenMax预加载动画完成后无法清除,因此我无法访问我的网站吗? 我该如何解决? - Can’t clear my TweenMax preload animation after it finishes so I can’t access my website? How do I resolve this? 如何解决无限的Javascript承诺? - How do I resolve an infinite Javascript promise?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM