乐趣区

「 JS 」快速上手异步方案

问题: 解决异步回调的深层嵌套的问题.(回调地狱)
1. Promise
promise 对象用于表示一个异步操作的最终状态,promise 在回调代码和将要执行这个任务的异步代码之间提供了一种可靠的中间机制来管理回调。
// 构造函数, 回调函数是同步的回调
new Promise(function(resolve,reject){
….// 异步操作
})
Promise 的实例对象有三个状态

 pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败

resolve 和 reject 分别是两个函数, 当在回调中调用时, 会改变 promise 实例的状态,resolve 改变状态为成功,reject 为失败.
then
Promise.prototype.then()
当 promise 对象的状态发生改变时,绑定在其身上的 then 方法就会被调用。then 方法包含两个参数:onfulfilled 函数 和 onrejected 函数,它们都是 Function 类型。当 Promise 状态为 fulfilled 时,调用 then 的 onfulfilled 方法,当 Promise 状态为 rejected 时,调用 then 的 onrejected 方法,所以在异步操作的完成和绑定处理方法之间不存在竞争,then() 方法返回一个 Promise 对象.
返回值
then 方法返回一个新的 Promise,而它的行为与 then 中的回调函数的返回值有关:

如果 then 中的回调函数返回一个值,那么 then 返回的 Promise 将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
如果 then 中的回调函数抛出一个错误,那么 then 返回的 Promise 将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
如果 then 中的回调函数返回一个已经是接受状态的 Promise,那么 then 返回的 Promise 也会成为接受状态,并且将那个 Promise 的接受状态的回调函数的参数值作为该被返回的 Promise 的接受状态回调函数的参数值。
如果 then 中的回调函数返回一个已经是拒绝状态的 Promise,那么 then 返回的 Promise 也会成为拒绝状态,并且将那个 Promise 的拒绝状态的回调函数的参数值作为该被返回的 Promise 的拒绝状态回调函数的参数值。
如果 then 中的回调函数返回一个未定状态(pending)的 Promise,那么 then 返回 Promise 的状态也是未定的,并且它的终态与那个 Promise 的终态相同;同时,它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。

catch
catch() 方法返回一个 Promise,并且处理拒绝的情况。
Promise.prototype.catch()
事实上,catch 方法相当于 then 方法的第二个参数方法, 触发拒绝状态.
注意, 如果调用 then 的 Promise 的状态(fulfillment 或 rejection)发生改变,但是 then 中并没有关于这种状态的回调函数,那么 then 将创建一个没有经过回调函数处理的新 Promise 对象,这个新 Promise 只是简单地接受调用这个 then 的原 Promise 的终态作为它的终态。所以在链式上, 最终会执行到 catch 上.
// 链式示例
new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(“1”);
resolve();
}, 1000);
}).then(function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(“2”);
// resolve();
reject();
}, 1000);
});
}).then(function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(“3”);
resolve();
}, 1000);
});
}).then(function () {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(“4”);
resolve();
}, 1000);
});
}).catch(function(){
console.log(“catch”);
})

2. genarator
symbol
新的一种基础数据类型 symbol, 表示独一无二的值. 它通常作为对象的属性键, 内置对象普遍存在该值.
// 一般用法, 它并不是构造器, 不能通过 new, 会报错.
let sym = Symbol();

// 在对象中表现形式, 要用 [] 包裹, 不然会被认为是 string.
var obj = {
[Symbol()]:”value”;
}
该属性是匿名, 所以不可枚举, 只能通过.getOwnPropertySymbols()返回的数组.
// 想要获得两个相同的 Symbol, 得通过.for()

Symbol(“asd”) === Symbol(“asd”) // false
Symbol.for(“asd”) === Symbol.for(“asd”) // true
Iterator
迭代器, 存在于特定几种可枚举的数据类型中.
// 一般用以下这种形式的键保存了迭代器函数.
// arr[Symbol.iterator]

aarr[Symbol.iterator]().next() // 遍历下一个, 返回 value 和 done,value 表示值,done 表示是否可以继续遍历下一个.

//for…of 循环遍历就是基于此, 必须该数据类型有迭代器.
回到 generator
// 表现形式
function* test(){

yield 1; // 任务 1

yield 2; // 任务 2

yield 3; // 任务 3

yield 4 ; // 任务 4
}
// 调用该方法会返回一个含有迭代对象的对象.
var obj = text();
obj.next(); // 调用该方法时, 每次到一个 yield 处停止.
3. async/await
作用:

简化 promise 的使用编码, 不通过 then()/catch()来指定回调函数
以同步编码方式实现异步流程

async function test (){

// 等待状态改变, 自动执行到下一个 wait 处
var flag = await new Promise((resolve,reject)=>{

setTimeout(function(){

// 状态改变
resolve(data); // 这里面的值传递给 flag
},1000)
})
// 通过 flag 传递数据
flag = await new Promise((resolve,reject)=>{

setTimeout(function(flag){

// 状态改变
resolve(flag);
},1000,flag)
})
}

test().catch(function(err){
// 处理异常
});

退出移动版