解释
Promise
是一个 javascript 对象,它代表了一个异步操作的最终完成或者失败。常用于控制异步操作的执行顺序,而且可以让异步方法像同步方法那样返回值。它不能立即取得异步方法的返回值,但是它可以代理这个值,一旦异步操作完成,就会以及将值传递给相应的处理方法。
ES6 的
Promise
对象是一个代理对象,被代理的值在Promise
对象创建时可能是未知的,另外它允许你为异步操作的成功和失败分别绑定相应的处理方法。
用途
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列
状态
pending
: 初始状态,既不是成功,也不是失败状态。fulfilled
: 意味着操作成功完成。rejected
: 意味着操作失败。
方法
- resolve
-
reject
触发promise状态的改变
- then
-
catch
两者都会返回一个
Promise
。then最多需要有两个参数:Promise 的成功和失败情况的回调函数.catch 只会返回失败的情况.
- all
Promise.all()
方法返回一个Promise
, 在可迭代(iterable
)参数中所有的 promises 都已经解决了或者当iterable
参数不包含 promise 时, 返回解决。或者返回拒绝, 当传递的 promise 包含一个拒绝(reject)时。 - race
Promise.race()
方法返回一个 promise,并伴随着 promise对象解决的返回值或拒绝的错误原因, 只要iterable
中有一个 promise 对象”解决(resolve)”或”拒绝(reject)”。
案例
- mysql连接池
var mysql = require('mysql');
const { dbConfig } = require('../config.js');
var pool = mysql.createPool(dbConfig);
var db = {};
db.q = function (sql,params) {
return new Promise((resolve,reject)=>{
// 取出链接
pool.getConnection(function(err, connection) {
if (err) {
reject(err);
return;
}
connection.query(sql,params, function (error, results) {
// 释放连接
connection.release();
if(error) {
reject(err);
return;
}
resolve(JSON.parse(JSON.stringify(results)));
});
});
});
}
// 导出对象
module.exports = db;
- 模拟axios
const URL_ERR = "地址错误"
const METHOD_GET = "GET"
const DEFAULT_CONTENT_TYPE = "application/json;charset=utf-8"
const myaxios = (url, ...arg) => {
let options = arg[0]
return new Promise((resolve, reject) => {
// 参数检测
let err = vaildContent(url, options)
if (err) {
reject(err)
}
// 参数解析
let type = (options && options.method) ? options.method : METHOD_GET
let contentType = (options && options.header) ? options.header : DEFAULT_CONTENT_TYPE
// application/x-www-form-urlencoded
// application/json
// ...
let params = setParams(contentType, options)
let sUrl = setUrl(url, options)
// 请求
var xhr = new XMLHttpRequest();
console.log(type, sUrl, contentType);
xhr.open(type, sUrl, true);
xhr.setRequestHeader("Content-Type", contentType);
xhr.send(params);
xhr.onreadystatechange = function() {
console.log(xhr.readyState);
if (xhr.readyState == 4) {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText))
} else {
// console.log(xhr);
let errObj = { status: xhr.status, errText: xhr.statusText }
if (xhr.responseText) errObj.errObj = errObj
reject(errObj)
}
}
};
})
}
const vaildContent = (url, opt) => {
if (!url) {
return URL_ERR
}
// TODO
return null
}
const setParams = (contentType, opts) => {
// contentType 对应不同的编码格式;这里默认JSON
return opts.data ? JSON.stringify(opts.data) : null
}
const setUrl = (url, opts) => {
let params = opts.params
if (!params) return url
// json
if (opts.method.toUpperCase() == "GET") {
let key = ""
for (let i in params) {
key += `&{i}={params[i]}`
}
key = "?" + key.slice(1)
return url + key
}
}