实现 node-mysql 实现异步操作之前,先来谈谈 JS 中的异步操作。
在 ES6 中提供了 Promise 对象
Promise 对象的三种状态
- pending(进行中)
- fulfilled(已成功)
- rejected(已失败)
状态的转换还是单向不可逆的过程
pending -> fulfilled
pending -> rejected
基本使用
Promise 定义后,有 resolve 和 reject 两个参数,分别对应 pending -> fulfilled 状态 和 pending -> rejected 状态
// 定义
const promise = new Promise(function(resolve, reject) {
// 耗时较长的操作
// 加载图片,请求接口等
if (/* 异步操作成功 */){resolve(value);
} else {reject(error);
}
});
执行时,无论执行 resolve 还是 reject,返回的都是 Promise 对象,要拿到 Promise 对象 中的值,要在 then 中获取。then 可以有两个函数,分别对应 Promise 对象 中的 resolve 参数 和 reject 参数
// 使用
promise.then(function(resolve){...},function(reject){...})
模拟异步操作的例子
const timeout = (ms) => {return new Promise((resolve, reject) => {resolve('done job')
});
}
console.log(timeout(100)) // Promise {'done job'}
timeout(100).then(res => {console.log(res) // done job
})
仔细想想,promise 对象 中的数据从 then 中才能拿到数据,但是 then 这种链式调用还是可能造成回调地狱,如果可以像同步函数一样操作,让 timeout(100) 直接有返回值,那就更好了。
ES2017 标准引入了 async 函数,在 async 函数中 promise 对象 前用 await 就可以直接从 promise 对象 中直接拿到数据了。
对上面的例子进行修改
在 async 函数 中打印的值和在 then 中打印的一模一样
const timeout = (ms) => {return new Promise((resolve, reject) => {resolve('done job')
});
}
console.log(timeout(100)) // Promise {'done job'}
timeout(100).then(res => {console.log(res) // done job
})
const getStr = async () => {const str = await timeout(100);
console.log(str) // done job
}
getStr()