我有一个问题,我无法在异步foreach许诺中下订单。希望你能帮助我。
我有3个(承诺)函数,我希望在再次运行它们之前在foreach中运行它们。
以下代码:
var env = [
'dev',
'prd',
'tst',
]
env.forEach(currentEnv => {
Promise.resolve()
.then(firstFunction(currentEnv))
.then(secondFunction(currentEnv))
});
function firstFunction(env) {
new Promise(resolve => {
setTimeout(() => {
console.log('firstFunction ' + env)
resolve();
}, 2000);
}).catch((error) => {
console.log('something went wrong' + env + "error: " + error);
});
};
function secondFunction(env) {
new Promise(resolve => {
setTimeout(() => {
console.log('secondFunction ' + env)
resolve();
}, 1000);
}).catch(() => {
console.log('something went wrong')
});
}
结果:
secondFunction dev
secondFunction prd
secondFunction tst
firstFunction dev
firstFunction prd
firstFunction tst
预期:
firstFunction dev
secondFunction dev
firstFunction prd
secondFunction prd
firstFunction tst
secondFunction tst
希望你们能帮助我。
答案 0 :(得分:1)
首先,您需要实际从函数中返回promise,并将函数(不是函数调用的结果)提供给.then()
回调。
var env = [
'dev',
'prd',
'tst',
]
env.forEach(currentEnv => {
Promise.resolve()
.then(() => firstFunction(currentEnv))
.then(() => secondFunction(currentEnv))
});
function firstFunction(env) {
return new Promise(resolve => {
setTimeout(() => {
console.log('firstFunction ' + env)
resolve();
}, 2000);
}).catch((error) => {
console.log('something went wrong' + env + "error: " + error);
});
};
function secondFunction(env) {
return new Promise(resolve => {
setTimeout(() => {
console.log('secondFunction ' + env)
resolve();
}, 1000);
}).catch(() => {
console.log('something went wrong')
});
}
这样做足以使您的呼叫按“所有firstFunction()
个呼叫然后所有secondFunction()
个呼叫”的顺序排列。
但是,如果您需要创建下一个环境来等待当前环境的完成,则可以使用异步迭代器构造。这是一个相对较新的功能,因此我假设您至少使用Node 10.x。
var env = [
'dev',
'prd',
'tst',
];
function firstFunction(env) {
return new Promise(resolve => {
setTimeout(() => {
console.log('firstFunction ' + env)
resolve();
}, 2000);
}).catch((error) => {
console.log('something went wrong' + env + "error: " + error);
});
};
function secondFunction(env) {
return new Promise(resolve => {
setTimeout(() => {
console.log('secondFunction ' + env)
resolve();
}, 1000);
}).catch(() => {
console.log('something went wrong')
});
}
async function *getAsyncIterator(env) {
for (const currentEnv of env) {
await firstFunction(currentEnv);
await secondFunction(currentEnv);
yield currentEnv;
}
}
async function doStuff() {
for await (const currentEnv of getAsyncIterator(env)) {
console.log(`Complete work on ${currentEnv}`)
}
}
doStuff();
更新:
最后,如果必须支持某些较旧的节点版本,第三个选择是应用递归算法。
var env = [
'dev',
'prd',
'tst',
];
function firstFunction(env) {
return new Promise(resolve => {
setTimeout(() => {
console.log('firstFunction ' + env)
resolve();
}, 2000);
}).catch((error) => {
console.log('something went wrong' + env + "error: " + error);
});
};
function secondFunction(env) {
return new Promise(resolve => {
setTimeout(() => {
console.log('secondFunction ' + env)
resolve();
}, 1000);
}).catch(() => {
console.log('something went wrong')
});
}
function doStuff(env = []) {
if (env.length === 0) return;
const [ currentEnv, ...restEnvs ] = env;
return Promise.resolve()
.then(() => firstFunction(currentEnv))
.then(() => secondFunction(currentEnv))
.then(() => doStuff(restEnvs));
}
doStuff(env).then(() => console.log('job done'));
答案 1 :(得分:0)
您好,非常感谢您的帮助。我玩了一段时间,想出了这个解决方案:
let promise = Promise.resolve();
env.forEach(thisEnv => {
promise = promise
.then(() => firstFunction(thisEnv))
.then(() => secondFunction(thisEnv))
});
promise.then(() => {
doneBuilding()
});