调用内部有更多异步函数的异步函数
Posted
技术标签:
【中文标题】调用内部有更多异步函数的异步函数【英文标题】:Calling asynchronous functions with more asynchronous functions inside 【发布时间】:2018-11-17 12:44:51 【问题描述】:我在尝试调用数组内的异步函数链时遇到问题。当我单独调用该函数时,它可以正常工作,如下例所示:
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。我不在乎是否需要安装一些插件来解决这个问题。
【问题讨论】:
这段代码使用了 Promise 构造函数反模式... 【参考方案1】:你必须再次调用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);
)();
正如我在 cmets 中指出的,consoleAll
最好写成:
function consoleAll(str)
return console1(str).then(function()
return console2(str);
);
或:
async function consoleAll(str)
await console1(str);
await console2(str);
【讨论】:
非常感谢,它真的救了我。我已经为这个问题奋斗了将近一天。 @kanzas 很高兴为您提供帮助 :)【参考方案2】:如果你调用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
之后,其余的promise 被随机执行。还请记住,resolve()
不会停止您在函数中执行的任何内容。会被执行!然而,一旦你调用 Promise,Promise 就会从 Pending 变为 Resolved,并且它总是会返回 resolve 中的第一个值。
【讨论】:
以上是关于调用内部有更多异步函数的异步函数的主要内容,如果未能解决你的问题,请参考以下文章
全局调用异步函数时出错:“等待仅在异步函数和模块的顶层主体中有效”?