我目前正在javascript中探索async / await的概念。我知道async函数会返回一个未来应该解决的promise并且它不会阻止代码的自然执行。这里我有一个代码,我写的是测试javascript的异步执行。
console.log("1")
async function asyncFunc(){
for(i=0;i<10000000;i++){
}
console.log("3")
}
asyncFunc().then(()=>{console.log('4')});
console.log("2");
我除了代码将以下列方式执行:
首先console.log()打印1
其次调用异步函数。由于异步代码是非阻塞的,因此最后一个console.log()将执行,从而在控制台中打印2。
之后执行async函数内的console.log()并在控制台中打印3。
最后,承诺将被解决,
then
内的console.log()将被执行并打印4。如此预期的产出:1,2,3,4
但实际上我的输出为1,3,2,4。
为什么它表现得像这样而不是我期望的方式
答案 0 :(得分:5)
该函数在完成运行之前不会返回一个promise(除非你await
内有另一个promise。)
循环运行(阻塞所有内容),然后评估console.log("3")
,然后返回一个promise。
调用函数继续运行(记录2)。
最后,释放事件循环并调用传递给then
的函数。
将函数标记为异步不会将其中的同步代码转换为异步代码。
答案 1 :(得分:1)
这里的答案很晚,昆汀是完全正确的,但有时候绘制这些东西很有帮助。让我们看一下非常简单的DECLARE @temp TABLE (DATETIME DATETIME, DATE DATE, tr INT, sh INT, tk VARCHAR(255))
INSERT INTO @temp (DATETIME, DATE, tr, sh, tk)
SELECT '2018-02-06 00:00:00', '2018-02-06', 447, 2144, '10000001'
UNION ALL
SELECT '2018-02-06 00:00:00', '2018-02-06', 447, 2144, '';
WITH Opt
AS (
SELECT *
FROM @temp t
WHERE t.tk = '' AND EXISTS (
SELECT *
FROM @temp x
WHERE cast(x.DATETIME AS DATE) = cast(t.DATETIME AS DATE) AND x.DATE = t.DATE AND x.tr = t.tr AND x.sh = t.sh AND x.tk <> t.tk
)
)
UPDATE Opt
SET tk = t.tk
FROM opt x
INNER JOIN @temp t
ON cast(x.DATETIME AS DATE) = cast(t.DATETIME AS DATE) AND x.DATE = t.DATE AND x.tr = t.tr AND x.sh = t.sh AND x.tk <> t.tk
SELECT *
FROM @temp
函数:
async
该功能分为两部分:
async function foo() {
console.log("a");
await something();
console.log("b");
return 42;
}
或await
(或者如果它刚刚结束)。所以在上面,那是return
和对console.log("a");
的调用(但不是等待其结果的位)。something
。如果我们用明确的承诺重写该函数,它看起来就像这样(挥手细节):
await
所以看看你的功能:
function foo() {
console.log("a");
return something().then(() => {
console.log("b");
return 42;
});
}
...我们可以看到函数中所有的代码都位于其初始同步部分中,并且它返回的承诺将通过async function asyncFunc(){
for(i=0;i<10000000;i++){
}
console.log("3")
}
解析。
那么为什么 do undefined
函数有同步部分?出于同样的原因,您传递到async
的执行程序函数同步运行:因此它可以立即启动其工作。
假设我们想在new Promise
周围做一个async
包装,我们期待JSON响应:
fetch
如果没有同步部分(对async function fetchJSON(...args) {
const response = fetch(...args);
return response.json();
};
的调用),它将永远不会做任何事情,它的承诺将永远无法解决。