编辑:我知道如何使用async / await使它正常工作,但不幸的是,由于它不受广泛支持(尤其是iOS 10,Internet Explorer等),我无法使用它。所以我只需要一个承诺。
我对Promises非常陌生,所以被困住了。我有这个for循环,只要我等于2(例如),我就想打破它。我曾尝试放置->
,但仍继续进行到reject
。我希望它在满足我的条件时停止。
i<10
当前输出:
for (let i = 0, p = Promise.resolve(); i < 10; i++) {
p = p.then(_ => new Promise((resolve, reject) => {
setTimeout(function() {
console.log(i);
if (i == 2) {
reject("BREAK HERE");
} else {
resolve();
}
}, Math.random() * 1000)
})).catch(err => {
console.log(err);
});
}
我希望它是:
0
1
2
BREAK HERE
3
4
5
6
7
8
9
答案 0 :(得分:0)
删除catch
,否则将捕获并处理错误。要记录日志而不是错误,请使用console.log
:
try {
for (let i = 0, p = Promise.resolve(); i < 10; i++) {
p = p.then(_ => new Promise((resolve, reject) => {
setTimeout(function() {
console.log(i);
if (i == 2) {
reject(console.log("BREAK HERE"));
} else {
resolve();
}
}, Math.random() * 1000)
}));
}
} catch (e) {}
答案 1 :(得分:0)
无论如何,您的代码将始终执行10次,因为setTimeout是异步操作,并且直到满足您的条件reject("BREAK HERE")
时,已经保证的链接都已链接十次。
这是可以做的,尽管看起来很乱:(
for (let i = 0, p = Promise.resolve(); i < 10; i++) {
p = p.then(data => new Promise((resolve, reject) => {
setTimeout(function() {
if(data && data.isRejected){
resolve({ isRejected: true })
return;
}
console.log(i);
if (i == 2) {
reject("BREAK HERE");
} else {
resolve({});
}
}, Math.random() * 1000)
})).catch(err => {
console.log(err);
/* add this line */
return { isRejected: true };
});
}
从catch中返回一个对象(而不是抛出)将把诺言标记为已解决。 docs中的更多内容 这将为您提供所需的结果
答案 2 :(得分:0)
据我了解,您的问题是,您想在宣誓之后顺序履行一个诺言。然后,您想在第一个承诺失败后立即中止。
为确保执行顺序,尽管您失去了并发运行时的实际好处,但必须在for循环中这样做。此代码将顺序运行:
const delay = async () => new Promise((resolve) => setTimeout(() => resolve(), Math.random() * 1e3);
const myUpload = async (file) => {
await delay();
if (file === 2) {
return Promise.reject(`COULD NOT UPLOAD ${file}`);
} else {
console.log("uploaded file", file);
return;
}
};
const uploadFilesSequentually = async (files) => {
for (const file of files) {
await myUpload(file); // this will create, and wait for the promise to finish or fail, only then the for loop continues
}
};
如果您不关心执行顺序并且可以考虑并发性,那么我会执行以下操作:
const promises = myFiles.map(myUpload); // all promises are now pending and will resolve in different orders
Promise.all(promises) // returns its own promise then resolves once all of them have succeded or is rejected as soon as one is rejected
.then((result) => console.log("everything uploaded"))
.catch(console.error);
(Promise.all
的结果将保持结果的顺序。因此,即使第三个promise在第一个promise之前解决,结果也将是[resultPromise1, resultPrimise2, resultPromise3, ... ]
)
答案 3 :(得分:0)
就目前而言,我最终使用了另一种方式来实现这一目标而没有承诺:
var i=0;
function fetchNext(){
if (i==2) {
console.log("BREAK HERE");
} else {
setTimeout(function () {
console.log(i);
i++;
fetchNext();
}, Math.random() * 1000);
}
}
fetchNext();
答案 4 :(得分:0)
for (let i = 0, p = Promise.resolve(); i < 10; i++) {
p = p.then(_ => new Promise((resolve, reject) => {
setTimeout(function() {
console.log("i",i);
if (i == 2) {
console.log("break here")
} else {
resolve();
}
}, Math.random() * 1000)
})).catch(err => {
console.log("err",err);
});
}
但是由于这段代码本身打算对异步调用进行排序,所以应该考虑这样做:
// repeated call
next(
0/*state*/,
i=>i<2/*match*/,
i=>i+1/*increment*/,
asyncCallPromisefied/*promise|promise[]*/,
[0]/*args*/
)
.catch(console.log)
// traverse array
next(
0/*state*/,
i => i < 6/*match*/,
i => i + 1/*increment*/,
asyncChain()/*promise|promise[]*/,
[0]/*args*/,
0/*[promise[] index]*/
)
.catch(console.log)
// helper
function next(state, match, increment, action, args, pointer = 0/**inactive**/){
if(match(state))
if(Array.isArray(action)){
return pointer < action.length
? action[pointer](...args)
.then(i => next(
increment(state),
match,
increment,
action,
[i],
pointer + 1
))
: undefined;
} else {
return action(...args)
.then(i => next(
increment(state),
match,
increment,
action,
[i]
))
}
}
// wrapper
function asyncCall(i, callback){
return setTimeout(() => {
console.log(i == 2 ? 'break here': i);
callback(null, ++i);
}, Math.random() * 1000)
}
function asyncCallPromisefied(i){
return new Promise(function(resolve, reject){
asyncCall(i, function(err, args){
if(err){
reject(err)
} else {
resolve(args)
}
})
})
}
function asyncChain(){return [
function(i){console.log("chain",i);return Promise.resolve(i)},
function(i){console.log("chain",i);return Promise.resolve(i)},
function(i){console.log("chain",i);return Promise.resolve(i)},
asyncCallPromisefied,
function(i){console.log("chain",i);return Promise.resolve(i)},
]}
答案 5 :(得分:0)
删除循环中的WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
,然后再处理。
.catch