gpt4 book ai didi

javascript - 当 Promise 被拒绝时,Promise 按顺序不会停止

转载 作者:行者123 更新时间:2023-12-01 03:37:34 28 4
gpt4 key购买 nike

我有一份 promise list 。

var p1 = {
run: function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Promise 1 done");
}, 2000);
})
}
};

var p2 = {
run: function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
reject("Promise 2 reject");
}, 1000);
})
}
};

var p3 = {
run: function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Promise 3 done");
}, 1500);
})
}
};

我想按顺序执行[p1,p2,p3]。我编写了一个函数 Process.sequence ,其行为类似于 Promise.all() (当所有 promise 都解决时解决,并在 promise 拒绝后立即拒绝)

Process = {
sequence: function(promises){
window.promises = promises;
return new Promise(function (resolve, reject) {
promises.reduce(function (sequence, promise) {
return sequence.then(function () {
return promise.run();
}).then(function (result) {
console.log(result);
if (promises.indexOf(promise) == promises.length - 1) {
resolve("All Done");
}
}).catch(function (reason) {
reject(reason);
});
}, Promise.resolve());
});
}
};

但是当我运行Process.sequence时...

Process.sequence([p1,p2,p3]).then(function(result){
console.log(result);
}, function(reason){
console.log(reason);
});

...即使p2之前被拒绝,p3仍然执行。

这是我期望的结果:

Promise 1 done
Promise 2 reject

但这才是真正的结果:

Promise 1 done
Promise 2 reject
Promise 3 done

我的函数Process.sequence出了什么问题?

更新

感谢@JaromandaX的支持。函数Process.sequence应该是这样的。

Process = {
sequence: function(promises) {
return promises.reduce(function(sequence, promise) {
return sequence.then(function() {
return promise.run();
}).then(function(result) {
console.log(result);
});
}, Promise.resolve()).then(function() {
return "All Done";
});
}
};

最佳答案

由于您希望结果包含所有已实现的值,并且只有在所有先前的值都已实现时才创建(“运行”) promise ,因此您应该进行一些更改:

  • 使循环异步,因为只有在前一个 promise 解决后,您才能知道是否继续下一个 promise 。
  • 当 Promise 被拒绝时停止循环
  • 随着进展将结果连接到数组中

此外,当变量不是 Promise 对象时,我不会将其称为“promise”……这只会带来困惑。称之为任务之类的。这里的 promise 是 task.run() 方法返回的内容。

以下是我建议的做法:

// The p1, p2, p3 objects have been written more concisely using a helper function:
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

const p1 = { run: _ => wait(2000).then(_ => "Promise 1 fulfilled") };
const p2 = { run: _ => wait(1000).then(_ => { throw "Promise 2 rejected" }) };
const p3 = { run: _ => wait(1500).then(_ => "Promise 3 fulfilled") };

const Process = {
sequence: function (tasks) {
return (function loop(results) {
return results.length >= tasks.length
// All promises were fulfilled: return the results via a promise
? Promise.resolve(results)
// Create the next promise
: tasks[results.length].run()
// When it fulfills, collect the result, and chain the next promise
.then(value => loop(results.concat(value)))
// When it rejects, return a rejected promise with
// the partial results and the reason of rejection
.catch(reason => { throw results.concat(reason) });
})([]); // Start with an empty results array
}
};

console.log('Wait for the results to come in...');
Process.sequence([p1, p2, p3]).then(function(result){
console.log('Fulfilled: ', result);
}).catch(function(reason){
console.log('Rejected: ', reason);
});

随着浏览器开始支持async/await,您还可以使用这个看起来更程序化的代码:

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

const p1 = { run: _ => wait(2000).then(_ => "Promise 1 fulfilled") };
const p2 = { run: _ => wait(1000).then(_ => { throw "Promise 2 rejected" }) };
const p3 = { run: _ => wait(1500).then(_ => "Promise 3 fulfilled") };

const Process = {
sequence: async function (tasks) {
const results = [];
for (let task of tasks) {
try {
results.push(await task.run());
} catch(err) {
throw results.concat(err);
}
}
return results;
}
};

console.log('Wait for the results to come in...');
Process.sequence([p1, p2, p3]).then(function(result){
console.log('Fulfilled: ', result);
}).catch(function(reason){
console.log('Rejected: ', reason);
});

关于javascript - 当 Promise 被拒绝时,Promise 按顺序不会停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44149182/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com