您的位置:首页 > 其它

Promise 基础 与 使用套路

2018-03-03 19:37 155 查看
Promise 是 ES6 中内置支持的对象

其构造函数接受一个参数, 该参数是一个函数, 该函数有两个参数, 两个参数都是函数, 一个在成功时调用(resolve), 一个在出错时调用(reject)

let myPromise = new Promise(
function(resolve, reject){
if (成功){
resolve(数据 或 另一个 Promise);
}else{
reject(出错信息)
}
}
);


reject 的参数是 错误信息, 如网络异常, 或用户逻辑错误信息

resolve 的参数一般是 处理(如网络访问)后的数据, 也可以是 另一个 Promise

then 方法

Promise 的对象(如 myPromise) 可以调用 then 方法, then 方法 接受两个参数, 一个是 成功时的回调, 一个是出错时的回调

function resolved(数据){
};
function rejected(错误信息){
};
myPromise.then(resolved, rejected)


注意: 千万不要误解 是 Promise的参数 函数 中直接调用的 resolved 和 rejected, Promise的参数 函数 中的 resolve 方法 和 reject 方法 是 Javascript引擎实现的, 它们的作用是 修改 当前 Promise 的 状态 从 等待 到 成功完成 或是 从 等待 到 出错完成.

而 then 方法 做的是 设置一个 callback, 该 callback 会在 Promise 状态改变时 调用 then方法中给定的 resolved 或 rejected 参数函数

简单的例子

let promise = new Promise(function(resolve, reject){
resolve("hello world");
});

promise.then(function(data){
console.log(data);
})

输出:
hello world


复杂点的网络异步的例子

function fetchData(url){
const promise = new Promise(function(resolve, reject){
// 构造 一个 ajax 请求
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = function(){
if (this.readyState != 4) { return; }
if (this.status == 200){
// 当网络请求成功时调用 resolve 方法, 并传入获取的数据
resolve(this.response);
}else{
reject(new Error(this.statusText));
}
};;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
}

fetchData("data1.json").then(
function(data){
console.log(data);
}
)


上面then方法给定的 resolved 函数 只是简单的 打印了获得的数据

Javascript 引擎提供的 resolve 方法 可以接受 两种类型的参数

第一种参数是除了Promise对象之外的普通对象, 这时 resolve 方法 会修改 当前 Promise的状态 为 成功完成, 并将 这个 普通对象 作为 处理的结果保存, 将来 传递给 then 方法 的 参数 函数 resolved 作为参数

第二种参数是Promise 对象, 当 resolve 方法发现 参数是 一个 Promise 时, 并不会更改 当前 Promise的 状态, 而是 会 跟踪 参数Promise 的状态, 即 不会立刻就 导致 then 的 resolved 参数函数的触发, 而是会 等 参数Promise 的 状态变化时 才触发, 并且 then 的 resolved 函数的参数 由这个 新的 Promise 中的 resolve 方法 给定

let p1 = new Promise(
function(resolve, reject){
resolve("hello");
}
)

let p2 = new Promise(
function(resolve, reject){
// 注: 并不会 改变 当前 Promise 的状态, 需要等待 p1 的执行结论
resolve(p1);
}
);

p2.then(function(data){
console.log(data);
})

输出:
hello


这种 resolve Promise 的特性开发人员似乎不会直接用到

另外 then 参数方法 resolved 是可以有返回值的, 因为 then 方法的返回值是 一个 新的 Promise, 因此可以 链式调用

promise.then(function(data){})

.then(function(data){})

.then(function(data){})

.then(function(data){})

因此可以实现 阶段性的 异步调用, 如 先访问一个 url, 根据获得的数据 访问 另一个 url

这时就可以利用 resolved 的方法的返回值

let p = new Promise(
function(resolve, reject){
resolve(1);
}
);

p.then(function(data){
console.log(data);
return 2
}).then(function(data){
console.log(data);
return 3
}).then(function(data){
console.log(data);
}).then(function(data){
console.log(data);
})
输出:
1
2
3
undefined


当返回值是一个 非 Promise 对象 的普通值, 则 then 返回的 Promise 直接就是 成功完成 的状态, 它的 then 方法 中的 resolve 方法 会被调用, 参数 就是 这个 普通值

当返回值是一个 Promise 对象, 则 then 方法 返回 的 Promise 对象 会 跟踪 该 Promise 对象的状态, 直到 这个 Promise 对象 的 状态 改变, 进而触发 then 的 resolve 方法 的调用

总结一下, then 方法 返回的 Promise 的 构造函数的参数函数 其实 是 resolve 了 then 方法 的 resolved 参数函数 的返回值, 这就是利用 之前那个特性实现的

function fetchData(url){
const promise = new Promise(function(resolve, reject){
const handle = function(){
if (this.readyState != 4) { return; }
if (this.status == 200){
resolve(this.response);
}else{
reject(new Error(this.statusText));
}
};
const client = new XMLHttpRequest();
client.open("GET", url);
client.onreadystatechange = handle;
client.responseType = "json";
client.setRequestHeader("Accept", "application/json");
client.send();
});
return promise;
}

fetchData("data1.json").then(
function(data){
// 第一把结果获得
console.log(data);
// 业务没有完成, 继续发起请求
return fetchData(data.nextURL)
}
).then(
function(data){
// 第二把结果返回
console.log(data);
}
)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ES6 Promise