寻找 Bluebird promise 函数 "any" 作为系列
Looking for Bluebird promise function "any" as series
我有一个要求运行Promise.any系列。
因为它不可用(我说得对吗?)我写了一个函数来连续执行 promises(在 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。
一种更简单的方法是简单地遍历您的输入值和 await
承诺。
- 您有一组值,
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);
});
如果您想通过忽略任何错误来处理数组 'fault tolerant',您可以在 for
循环中添加一个 try { ... } catch {}
。如果您想要 series
解析为的默认值,请在 async function
的末尾添加 return ...;
而不是 throw
。
我有一个要求运行Promise.any系列。
因为它不可用(我说得对吗?)我写了一个函数来连续执行 promises(在 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。
一种更简单的方法是简单地遍历您的输入值和 await
承诺。
- 您有一组值,
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);
});
如果您想通过忽略任何错误来处理数组 'fault tolerant',您可以在 for
循环中添加一个 try { ... } catch {}
。如果您想要 series
解析为的默认值,请在 async function
的末尾添加 return ...;
而不是 throw
。