如何正确地兑现承诺?

时间:2019-09-09 17:24:55

标签: javascript ecmascript-6 promise

我在javascript(es6)中使用诺言时遇到了问题。

到目前为止,我已经使用了Promise,但没有那么广泛,在这个项目中,我需要将Promise内的Promise链接起来,并确保在我继续其余任务之前要等一个结论。

这是我的代码示例:


myArray = ['element1', 'element2', /*...*/]
const function1 = () => {
    return function2()
             .then(() => {
                 console.log('first to fire')
                 return myArray
                     .reduce(async(previousPromise, element) => {
                          console.log('reduce', element)
                          await previousPromise
                          return function3(element)
                     }, Promise.resolve())
             })
             .then(() => {
                 console.log('this should fire last but actually fires before the last function3() is done')
             })
}
/*
function1 => the function I'm trying to create, which should return a promise. 

function2 => an external function that I have no control. this function
is asynchronous and returns a promise.

function3 => this is also an asynchronous external function that
returns a promise that I should execute to get what I need. It 
receives as parameter a value which I have in myArray, and it should
execute successively one after the other (for example as if 'element2'
was dependent of 'element1', and so on). 
*/

由于我得到的结果是(只有2个元素的myArray),我不知何故不能正确地链接此诺言:

>first to fire
>reduce element1
>reduce element2
>this should fire last but actually fires before the last function3() is done
>a log I've added inside of function3 which corresponds to 'element1'
>a log I've added inside of function3 which corresponds to 'element2'

所以...基本上,我需要一切“等待”,直到所有诺言都完成了。我该怎么做呢?

2 个答案:

答案 0 :(得分:1)

我不明白您的代码为什么不起作用(问题很可能出在sql ="SELECT COUNT(*) AS num FROM conteo WHERE party =1"; ResultSet rs = conn.createStatement().executeQuery(sql); if (rs.next()) { int i = rs.getInt("num"); ... } 内部,它过早实现了返回的承诺),但是您应该尝试保持简单:

sql ="SELECT COUNT(*) FROM conteo WHERE party =1";
ResultSet rs = conn.createStatement().executeQuery(sql); 
if (rs.next()) {
    int i = rs.getInt(1); // access first column in result
    ...
}

答案 1 :(得分:0)

您应该使用await从function3获取结果。声明新功能时,还需要使用async。工作示例:

myArray = ['element1', 'element2', 'element3']

const function1 = async() => {
  return function2()
    .then(async(results) => {
      console.log('first to fire with ' + results)
      return await myArray.reduce(async(accumP, element) => {
        console.log('reduce', element)
        return await accumP + await function3(results, element)
      }, Promise.resolve(''))
    })
    .then((finalResults) => {
      console.log('this should fire last... and does, with ' + JSON.stringify(finalResults))
    })
}

const function2 = async() => new Promise((resolve) =>
  setTimeout(() => resolve('foo '), 10))

const function3 = async(prefix, element) => new Promise((resolve) =>
  setTimeout(() => resolve(prefix + element + ' bar, '), 50))

function1()

正如其他人在评论中指出的那样,如果您仍然能够使用await,则可以通过不使用then并始终使用await来大大简化自己的理解过程

myArray = ['element1', 'element2', 'element3']

const function1 = async() => {
  const f2results = await function2()

  const f3results = await myArray.reduce(async(accumP, element) => {
    console.log('reduce', element)
    return await accumP + await function3(f2results, element)
  }, Promise.resolve(''))

  console.log('this should fire last... and does, with ' + JSON.stringify(f3results))
}

const function2 = async() => new Promise((resolve) =>
  setTimeout(() => resolve('foo '), 10))

const function3 = async(prefix, element) => new Promise((resolve) =>
  setTimeout(() => resolve(prefix + element + ' bar, '), 50))

function1()