Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
异步标记是否用承诺包装JavaScript函数?_Javascript_Node.js_Asynchronous_Promise_Async Await - Fatal编程技术网

异步标记是否用承诺包装JavaScript函数?

异步标记是否用承诺包装JavaScript函数?,javascript,node.js,asynchronous,promise,async-await,Javascript,Node.js,Asynchronous,Promise,Async Await,所以我理解“异步”确保函数将返回一个承诺,如果不返回,则将其包装在一个承诺中 我的问题是,如果函数已经返回了一个承诺,“async”是否将其包装在另一个承诺中 异步函数,返回非承诺: async function foo() { return 5; } console.log(foo()) // Promise { 5 } function foo() { return Promise.resolve(5); } console.log(foo()) // Promise

所以我理解“异步”确保函数将返回一个承诺,如果不返回,则将其包装在一个承诺中

我的问题是,如果函数已经返回了一个承诺,“async”是否将其包装在另一个承诺中

异步函数,返回非承诺:

async function foo() {
    return 5;
}

console.log(foo()) // Promise { 5 }
function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { 5 }
async function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { <pending> }
常规功能,返回承诺:

async function foo() {
    return 5;
}

console.log(foo()) // Promise { 5 }
function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { 5 }
async function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { <pending> }
异步函数,返回承诺:

async function foo() {
    return 5;
}

console.log(foo()) // Promise { 5 }
function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { 5 }
async function foo() {
    return Promise.resolve(5);
}

console.log(foo()) // Promise { <pending> }
异步函数foo(){ 返还承诺。决议(5); } console.log(foo())//Promise{}
为什么最后一个返回“Promise{pending}”?我的直觉告诉我,冗余的“async”标记正在用另一个承诺包装已经返回的承诺。是否正确?

您需要调用上一个函数,如下所示:

foo.then(function(r){console.log(r)});
原因是,异步函数需要返回一个承诺。承诺将记录挂起,直到结果得到解决。要实现承诺,你必须称之为“then”

以下是一个链接,可获取更多关于以下内容的信息:

以下是有关异步函数的更多信息的链接:

如果
异步
函数返回承诺,则该函数返回的承诺将解析为与原始承诺相同的值。通过一个简单的例子可以看出这一点:

async function foo() {
  return Promise.resolve(42);
}
console.log(await foo()); // "42", not "Promise { 42 }"
因此,在大多数正常情况下,我们可以简单地想象异步函数体中的代码返回的承诺是在不被触碰的情况下返回的。但正如您偶然发现的,即使异步函数返回的承诺将解析为与代码返回的承诺相同的值,实际的承诺对象也不一定相同:

let p1;
async function foo() {
  p1 = Promise.resolve(42);
  return p1;
}
let p2 = foo();
console.log('p1 === p2 ?', p1 === p2); // "false" (!)
因此我们可以看到,函数调用返回的Promise对象实际上与函数体返回的Promise对象不同。不过,不管怎样,当我们等待它(或使用
Promise.then()
)时,它将给出相同的结果:

(请注意,要在例如node repl shell中运行这些示例,您需要将它们包装为:

async function main() {
  /* code using async / await here */
}
main();

现在我不确定
async
/
wait
的本机实现对于现代节点应用程序是什么,但是如果您看看
Babel
在传输到节点6时生成了什么

以这个简单的异步函数为例:

async function fooAsync() {
  return 1;
}
Babel将此代码转换为如下所示:

函数asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value;}catch(error){reject(error);return;}if(info.done){resolve(value)}else{Promise.resolve(value)。然后(_next,_throw)}
函数{u asyncToGenerator(fn){return function(){var self=this,args=arguments;返回新承诺(函数(resolve,reject){var gen=fn.apply(self,args);函数{u next(value){asynchgeneratorstep(gen,resolve,reject,{next,{u throw,“next”,value);}函数{asynchgeneratorstep(gen,resolve,reject,reject,{next,{throw,“throw”,err);}下一个(未定义);};};}
函数fooancy(){
return\u fooancy.apply(这是参数);
}
函数_fooancy(){
_fooancy=\u asyncToGenerator(函数*(){
返回1;
});
return\u fooancy.apply(这是参数);
}

您可以看到异步方法及其生成的状态机的转换。因此,为了回答您的问题,只要在函数中包含关键字
async
,它就会返回一个
Promise
。这也可以在
Typescript
中看到,如果您有
async
方法,并且没有指定一个不回答我的问题的
Promise

返回类型,编译器就会抱怨在第一个例子中,如果我不调用“then”,为什么它会返回“Promise{5}”@webbyweb我同意这个答案并没有回答你的问题,但是:控制台向你显示“Promise{5}”,因为你给console.log的对象是一个承诺,如果你要调用的话。then()在它上面,会给你一个值5。碰巧在你打印它的值时承诺已经解决了,但那是因为你用Promise.resolve()创建了它。如果你返回了一个未解决的承诺,console.log会显示“Promise{}”。谢谢@MykWillis,这非常有帮助。因此,如果异步函数已经返回承诺,那么该承诺将被取消包装,然后被包装在“异步”的新承诺中,这是否准确tag?@webbyweb基于这些实验,我认为这是一个公平的描述,尽管说实话,我不确定这是由规范决定的还是仅仅是一个特定的实现选择。但肯定的是,返回承诺的异步函数最终不会向其调用方返回嵌套承诺(也就是说,一个承诺会变成另一个承诺)。明白了,谢谢!顺便说一句,我相信你的回答,你的意思是在第二次定义“foo”时返回p1.我理解你的意思,但只是为了让其他阅读你答案的人更清楚地理解这个问题是的,我想返回p1,很抱歉遗漏。我编辑了答案。你必须接受承诺不是为了同步检查而设计的,同步检查有点可疑。行为可能是,也许应该更加一致。