使用异步函数返回Promise

时间:2018-06-18 23:22:39

标签: javascript node.js es6-promise

给出以下两种实现(在ES6 / NodeJS中)

async TestFunc() {
    return new Promise((resolve,reject) => {
        ...
    });
}

TestFunc() {
    return new Promise((resolve,reject) => {
        ...
    });
}

如果我这样调用其中任何一个函数,行为会有什么不同吗?

await TestFunc();

我认为第一个(异步)实现将返回一个promise,我们将等待返回另一个promise,而后者(同步)实现将返回promise,然后等待。但是,它们都按预期工作,让我有点困惑。

2 个答案:

答案 0 :(得分:4)

异步函数返回一个promise,该promise将由函数体中执行的return语句返回的值解析(如果在执行最后一行函数后返回,则使用undefined解析)

使用承诺解决承诺会使已解决的承诺在解决的承诺处于已解决的状态和结算承诺的价值时立即生效。

因此,在第一次调用时始终从异步函数体同步返回promise P 会立即将通过调用异步函数返回的promise的结果链接到 P 的结果。对于同步返回的promise,这是不必要的步骤,并且不需要函数的async声明。

如果TestFunc是异步函数,则为

await TestFunc();

await运算符的操作数是通过调用async函数生成的promise。这个承诺将通过函数体代码中返回的承诺来解决。

如果TestFunc不是异步函数,则为

await TestFunc();

await运算符的操作数是由TestFunc构造并返回的promise。有效的区别是TestFunc无法在内部使用await运算符而不将其更改回异步函数。

答案 1 :(得分:0)

function TestFunc() {
  return new Promise( resolve => {
    setTimeout(()=>{ resolve(42) }, 5000 );
  });
}

好的!我们已经导入了@ w0f的异步函数,我们决定将它与async / await一起使用。

然而,一个假设是错误的:我们需要改变@ w0f的功能来做到这一点。

相反,我们只使用async关键字允许在我们自己的函数中使用await

async function run(){
   const value = await TestFunc();
   // Now we can use the value just as if was a normal variable declaration.
   const total = value + 14;
}
run();
与承诺相同的是:

const promise = TestFunc();
promise.then(value => { 
  const total = value + 14;
});

任何对承诺不熟悉的人都会想“好吧,看起来不那么糟糕,现在我们只需要从承诺中解开价值!”。但是唉...

const promise = TestFunc();
let total;
promise.then(value => { 
  total = value + 14;
});

// ...it's not possible to unwrap a value from a promise while
// also knowing when the value has resolved - other than checking every now and then:

console.log( total ); // undefined
wait( 3000 );  // wait is a synchronous wait to be implemented by the reader :p
console.log( total ); // undefined
wait( 3000 );
console.log( total ); // 56, yay!

所以也许你花了几个月的时间来发明一些聪明且复杂的代码来检查一个值是否已经解决。恭喜你,你刚刚重新发明了承诺!

这就是等待如此简洁的原因。您实际上是在一个promise-wrapped值上运行,但是async / await使它看起来像一个正常的值。