你不能。原因如下:
Promise 是一种语言构造,它使 JavaScript 引擎能够继续执行代码,而无需等待内部函数(也称为执行器函数)的返回。 Promise 始终在事件循环内运行。
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
console.log(p);
基本上,promise 是回调的美化语法糖。我们将看到如何做,但首先让我们有一个更现实的代码:
function someApiCall(){
return new Promise(function(resolve, reject){
setTimeout(()=>{
resolve('Hello');
})
})
}
let data = someApiCall();
console.log(data);
这是所谓的异步代码,当 JavaScript 引擎执行它时,someApiCall 立即返回结果,在本例中是待处理的 Promise:
> Promise {<pending>}
如果您注意执行器,您会发现我们需要传递解析和拒绝参数(即回调)。是的,它们是语言构造所需的回调。当他们中的任何一个调用时,promise 将改变其状态并因此得到解决。我们不称其为已解决,因为解决意味着成功执行,但函数也可能出错。
我们如何获取数据?好吧,我们需要更多回调,一旦 Promise 解决,执行器函数就会调用这些回调:
var p = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
p.then((result) => {
console.log(result); // foo
}).catch((err) => {
console.log(err);
});
为什么我们需要传递单独的回调?因为一个人会被决心所满足,而另一个人会被拒绝。然后resolve函数会调用callback,reject函数会调用catchcallback。
Javascript 引擎将在闲暇时执行这些回调,对于常规函数来说,这意味着事件循环被清除,对于超时来说,时间到了。
现在回答你的问题,我们如何从 Promise 中获取数据。好吧,我们不能。
如果你仔细观察,你会发现我们并没有真正取出数据,而是继续提供回调。没有取出数据,而是传入回调。
p.then((result) => {
console.log(result);
}).catch((err) => {
console.log(err);
});
有人说使用等待:
async function() {
let result = await p;
}
但是有一个问题!我们必须将其包装在异步函数中。总是。为什么?因为 Async/await 是 Promise api 之上的另一个抽象或语法糖级别,无论您喜欢哪种。这就是为什么我们不能直接使用await而是总是将其包装在async语句中。
总而言之,当我们使用 Promise 或 async/await 时,我们需要遵循一定的约定并编写简洁的代码和紧密结合的回调。 javascript 引擎或像 babeljs 或 typescript 这样的转译器将这些代码转换为要运行的常规 javascript。
我可以理解您的困惑,因为人们在谈论承诺时一直说获取数据,但我们没有获取任何数据,而是传递回调以在数据准备好时执行。
希望现在一切都清楚了。