如何在 javascript 中使用 aynsc/await 从异步操作返回对象
How to use aynsc/await in javascript for returning objects from asynchronous operations
我一辈子都弄不明白为什么 async/await 会这样。
考虑这个例子。
我想要一个执行一些数据库初始化的函数,returns 完成后将数据库对象交给我。
var globalDb = null;
const IDB_DATABASE_NAME = "mydb";
const IDB_STORE_NAME = "mystore";
const IDB_VERSION = 1.0;
async function initDb() {
var idbOpenDbRequest = window.indexedDB.open(IDB_DATABASE_NAME, IDB_VERSION);
idbOpenDbRequest.onsuccess = function (event) {
return event.target.result;
};
}
(async () => {
globalDb = await initDb();
console.log("I should happen second")
console.log(globalDb);
})();
预计
- console.log("I should happen first")
- console.log("I should happen second")
- console.log(globalDb); //将对象转储到控制台
实际
- console.log("I should happen second")
- console.log(globalDb); //未定义
- console.log("I should happen first")
我意识到我从根本上误解了这里的某些东西。请赐教为什么 await 不能像我期望的那样工作。 :)
JsFiddle
https://jsfiddle.net/p2jqyrou/2/
Ps。忘记这是关于 indexedDb 的,并且这个例子非常简单——我认为这对这个问题的主题无关紧要。
所以问题出在您的 initDb
函数上。我会为您重写它,然后解释为什么这个版本有效:
function initDb() {
var idbOpenDbRequest = window.indexedDB.open(IDB_DATABASE_NAME, IDB_VERSION);
return new Promise((resolve, reject) => {
idbOpenDbRequest.onsuccess = function (event) {
setTimeout(function () {
console.log("I should happen first");
resolve(event.target.result);
}, 2000);
};
})
}
我所做的是将 onsuccess
回调包装在 Promise 中。 Javascript 中的 async/await 模式基本上基于 Promises。要么你自己return一个Promise,要么它把结果包装在一个Promise中(并立即解析它)。
因为您自己没有 return Promise,所以它试图将 return 值(未定义)包装在 Promise 中。然后它立即解决导致异步函数 return.
使用此更新后的代码 initDb
被调用,然后 return 是一个 Promise,它仅在建立连接并触发超时后才被解析。
我一辈子都弄不明白为什么 async/await 会这样。
考虑这个例子。
我想要一个执行一些数据库初始化的函数,returns 完成后将数据库对象交给我。
var globalDb = null;
const IDB_DATABASE_NAME = "mydb";
const IDB_STORE_NAME = "mystore";
const IDB_VERSION = 1.0;
async function initDb() {
var idbOpenDbRequest = window.indexedDB.open(IDB_DATABASE_NAME, IDB_VERSION);
idbOpenDbRequest.onsuccess = function (event) {
return event.target.result;
};
}
(async () => {
globalDb = await initDb();
console.log("I should happen second")
console.log(globalDb);
})();
预计
- console.log("I should happen first")
- console.log("I should happen second")
- console.log(globalDb); //将对象转储到控制台
实际
- console.log("I should happen second")
- console.log(globalDb); //未定义
- console.log("I should happen first")
我意识到我从根本上误解了这里的某些东西。请赐教为什么 await 不能像我期望的那样工作。 :)
JsFiddle
https://jsfiddle.net/p2jqyrou/2/
Ps。忘记这是关于 indexedDb 的,并且这个例子非常简单——我认为这对这个问题的主题无关紧要。
所以问题出在您的 initDb
函数上。我会为您重写它,然后解释为什么这个版本有效:
function initDb() {
var idbOpenDbRequest = window.indexedDB.open(IDB_DATABASE_NAME, IDB_VERSION);
return new Promise((resolve, reject) => {
idbOpenDbRequest.onsuccess = function (event) {
setTimeout(function () {
console.log("I should happen first");
resolve(event.target.result);
}, 2000);
};
})
}
我所做的是将 onsuccess
回调包装在 Promise 中。 Javascript 中的 async/await 模式基本上基于 Promises。要么你自己return一个Promise,要么它把结果包装在一个Promise中(并立即解析它)。
因为您自己没有 return Promise,所以它试图将 return 值(未定义)包装在 Promise 中。然后它立即解决导致异步函数 return.
使用此更新后的代码 initDb
被调用,然后 return 是一个 Promise,它仅在建立连接并触发超时后才被解析。