【问题标题】:Looking for Bluebird promise function "any" as series寻找蓝鸟承诺功能“任何”作为系列
【发布时间】:2021-08-22 08:22:06
【问题描述】:

我需要连续运行Promise.any

由于它不可用(对吗?)我编写了一个函数来串行执行承诺(在 Pomise.mapSeries 的帮助下)并在第一次测试时满意地解决。

方法是:

  • 关于测试功能的解析检查结果是否满足标准。
  • 如果条件不匹配,mapSeries 无论如何都会继续。
  • 如果条件匹配,则拒绝自定义错误。它会破坏 mapSeries。
  • 然后在 mapSeries 函数的 catch 中检查错误是否为自定义错误,如果存在自定义错误,则使用所需结果解决,否则进一步拒绝错误。

代码如下:

const Promise = require('bluebird')

let delay = 1000
const BIG = 10

function isBig (n) {
  return Promise.delay(delay).then(() => {
    console.log('[test] n: ', n)
    if (n < 0) return Promise.reject(new Error('Negative number'))
    else if (n > BIG) return Promise.resolve(n)
    else return Promise.resolve(false)
  })
  delay -= 100  // just to check array items are executing in series
}

function anySeries (arr, test) {
  return Promise.mapSeries(arr, n => {
    return isBig(n)
    .then(res => {
      if (res) {
        let err = new Error('Stop As Found')
        err.result = n
        return Promise.reject(err)
      } else {
        return res
      }
    })
  })
  .then(res => {
    console.log('[AS] each output: ' + JSON.stringify(res))
    return null
  }).catch(err => {
    console.log('[AS] Let me check error')
    if (/^Stop As Found$/.test(err.message)) {
      console.log('[AS] Found the desired')
      console.log('[AS] Final result: ', err.result)
      return Promise.resolve(err.result)
    } else {
      console.error('[AS] Internal error')
      console.error('[AS] Returing error: ', err.message)
      return Promise.reject(err)
    }
  })
}

let arr = [ 1, 11, 5, -1, 13, 15]
// find bigger than 10
console.log('---Test 1 (will find)---')
anySeries(arr, isBig)
.then(res => {
  console.log('Arr: %s, Big one: %s', arr, res)
  arr = [ 1, 3, 5]
  console.log('\n---Test 2 (will not find)---')
  return anySeries(arr, isBig)
})
.then(res => {
  console.log('Arr: %s, Big one: %s', arr, res)
  arr = [ 1, 2, -1, 13, 15, 2]
  console.log('\n---Test 3 (wiil result in error)---')
  return anySeries(arr, isBig)
})
.catch(console.error)

如果有更好的方法我想知道,最好使用 Promise。

【问题讨论】:

  • “我需要连续运行 Promise.any。”它“不可用”的原因是 Promise.any() 是一个承诺聚合器,如 Promise.all()Promise.race();它没有运行任何东西。
  • @Roamer-1888 谢谢你,理解你的意思,但是如果这个功能可用,那么它可能对许多人非常有用。

标签: javascript node.js promise bluebird


【解决方案1】:

一个更简单的方法是简单地循环你的输入值和await promise。

  • 你有一个值数组,arr
  • 您想将这些转换为一个承诺(一次一个),isBig
  • 如果值通过了一些检查if (res),则不要继续处理数组的其余部分
async function series(values, map, check) {
  for (let i = 0; i < values.length; i++) {
    const res = await map(values[i], i, values);
    if (check(res, i, values)) {
      return res;
    }
  }
  // This might be desirable or it might not. Up to you.
  throw new Error('No result');
}

series(arr, isBig, (res) => !!res)
  .then((result) => {
    // A value was resolved to.
    console.log('[AS] Found the desired');
    console.log('[AS] Final result: ', result);
  })
  .catch((err) => {
    console.error('[AS] Internal error');
    console.error('[AS] Returning error: ', err.message);
  });

如果您想通过忽略任何错误来处理数组“容错”,您可以在for 循环内添加try { ... } catch {}。如果您想要一个 series 解析为的默认值,请在 async function 的末尾添加 return ...; 而不是 throw

【讨论】:

  • 感谢@Rick,这种方法看起来简洁有趣。我必须将我的编码从 Promise 移到 ES6 async/await。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 2018-01-10
相关资源
最近更新 更多