我在尝试调用数组内的异步函数链时遇到了麻烦。当我单独调用该函数时,它可以正常工作,如下例所示:
function consoleAll(string) {
return new Promise(function (resolve) {
console1(string).then(function () {
console2(string).then(function () {
resolve();
});
});
});
}
function console1(value) {
return new Promise((resolve) => {
console.log(value + "1");
resolve()
});
}
function console2(value) {
return new Promise((resolve) => {
console.log(value + "2");
resolve()
});
}
consoleAll('value-')
在这种情况下,结果如下所示:
value-1
value-2
但是当它在循环中传递时,它不能正确地创建线程并且完全无序地调用函数
function consoleAll(string) {
return new Promise(function (resolve) {
console1(string).then(function () {
console2(string).then(function () {
resolve();
});
});
});
}
function console1(value) {
return new Promise((resolve) => {
console.log(value + "1");
resolve()
});
}
function console2(value) {
return new Promise((resolve) => {
console.log(value + "2");
resolve()
});
}
//Call
['h1-', 'h2-', 'h3-'].forEach(function (string) {
consoleAll(string)
});
这次不是写下面的结果:
h1-1
h1-2
h2-1
h2-2
h3-1
h3-2
输出这个:
h1-1
h2-1
h3-1
h1-2
h2-2
h3-3
它看起来像调用整个数组的console1函数然后调用console2。
是否有人知道拨打此电话的正确方法? PS。我不在乎是否需要安装一些插件来解决这个问题。
答案 0 :(得分:5)
在之前的异步调用完成后,您必须再次致电logAll
:
const values = ['h1-', 'h2-', 'h3-'];
(function next(i) {
if(i >= values.length) return;
consoleAll(values[i]).then(function() {
next(i + 1);
});
})(0);
或者,如果这是丑陋的,这是一种更现代的方式:
(async function() {
for(const string of ["h1-", "h2-", "h3"])
await consoleAll(string);
})();
正如我在评论中指出的那样,consoleAll
写得更好:
function consoleAll(str) {
return console1(str).then(function() {
return console2(str);
});
}
或:
async function consoleAll(str) {
await console1(str);
await console2(str);
}
答案 1 :(得分:1)
如果您致电new Promise(fn)
,则会立即执行fn
内部。所有.then都被推送到堆栈以便稍后执行,但首先整个.forEach
必须通过。
您可以在此代码中看到更多内容:
function consoleAll(string) {
return new Promise(function (resolve) {
consoleLog(string, 1).then(function () {
consoleLog(string, 2).then(function () {
resolve();
});
});
consoleLog(string, 3).then(function () {
consoleLog(string, 4).then(function () {
resolve();
});
});
});
}
function consoleLog(value, tag) {
return new Promise((resolve) => {
console.log(value + tag);
resolve()
});
}
//Call
['h1-', 'h2-', 'h3-'].forEach(function (string) {
consoleAll(string)
});
initialition
其余的承诺被执行后洗牌。还要记住,resolve()
不会阻止你执行的函数内的任何内容。它会被执行!但是,一旦你调用Promise,Promise就会从Pending变为Resolved,它将始终返回resolve中的第一个值。