FtD*_*Xw6 6 javascript promise
给定一个函数,fn它返回一个promise,以及一个任意长度的数据数组(例如data = ['apple', 'orange', 'banana', ...])如何按顺序将数组的每个元素上的函数调用链接起来,这样如果fn(data[i])解析,整个链完成并停止调用fn,但是如果fn(data[i])拒绝,下一个呼叫fn(data[i + 1])执行?
这是一个代码示例:
// this could be any function which takes input and returns a promise
// one example might be fetch()
const fn = datum =>
new Promise((resolve, reject) => {
console.log(`trying ${datum}`);
if (Math.random() < 0.25) {
resolve(datum);
} else {
reject();
}
});
const foundResult = result => {
// result here should be the first value that resolved from fn(), and it
// should only be called until the first resolve()
console.log(`result = ${result}`);
};
// this data can be purely arbitrary length
const data = ['apple', 'orange', 'banana', 'pineapple', 'pear', 'plum'];
// this is the behavior I'd like to model, only for dynamic data
fn('apple').then(foundResult)
.catch(() => {
fn('orange').then(foundResult)
.catch(() => {
fn('banana').then(foundResult)
.catch(() => {
/* ... and so on, and so on ... */
});
});
});
Run Code Online (Sandbox Code Playgroud)
我觉得也许这种模式的优雅解决方案是我所缺少的.这种行为非常相似Array.some(),但是我试图摆弄那种空洞.
编辑:我从数字数据切换到字符串,以强调解决方案不需要依赖于数字数据.
编辑#2:进一步澄清,fn可以是任何接受输入并返回承诺的函数.fn上面的实现只是为了给出一个完整的例子.实际上,fn实际上可能是API请求,数据库查询等.
你可以使用async/await和循环:
async function search() {
for (let item of data) {
try {
return await fn(item);
} catch (err) { }
}
throw Error ("not found");
}
search().then(foundResult).catch(console.log);
Run Code Online (Sandbox Code Playgroud)
fn 可以返回Promise(等待)或只返回一个值(返回)data可能是一个无限的iterable序列(发电机)如果序列失败,这是输出:
trying apple
trying orange
trying banana
trying pineapple
trying pear
trying plum
Error: not found
Run Code Online (Sandbox Code Playgroud)
对于异步的支持是在es2017天然的,但可transpiled到ES3/ES5与巴别或打字稿
| 归档时间: |
|
| 查看次数: |
241 次 |
| 最近记录: |