类别:js / 日期:2022-11-16 / 浏览:270 / 评论:0

Promise
解决的问题:回调地狱

Promise 规范:


promise 有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和“拒绝”也不能相互转换.
promise 必须提供一个 then 方法以访问其当前值、终值和据因。promise.then(resolve,reject),resolve 和 reject 都是可选参数。如果 resolve 或 reject 不是函数,其必须被忽略.

then 方法必须返回一个 promise 对象.

使用:

实例化 promise 对象需要传入函数(包含两个参数),resolve 和 reject,内部确定状态.resolve和 reject 函数可以传入参数在回调函数中使用.
resolve 和 reject 都是函数,传入的参数在 then 的回调函数中接收.
var promise = new Promise(function(resolve, reject) {
    setTimeout(function(){
       resolve('好哈哈哈哈');
    });
});
promise.then(function(val){
    console.log(val)
})
then 接收两个函数,分别对应 resolve 和 reject 状态的回调,函数中接收实例化时传入的参数.
promise.then(val=>{
    //resolved
},reason=>{
    //rejected
})
catch 相当于.then(null, rejection)
当 then 中没有传入 rejection 时,错误会冒泡进入 catch 函数中,若传入了 rejection,则错误会被 rejection 捕获,而且不会进入 catch.此外,then 中的回调函数中发生的错误只会在下一级的 then 中被捕获,不会影响该 promise 的状态.
new Promise((resolve, reject) => {
    throw new Error('错误')
}).then(null, (err) => {
    console.log(err, 1);//此处捕获
}).catch((err) => {
    console.log(err, 2);
});
// 对比
new Promise((resolve, reject) => {
    throw new Error('错误')
}).then(null, null).catch((err) => {
    console.log(err, 2);//此处捕获
});
// 错误示例
new Promise((resolve, reject) => {
    resolve('正常');
}).then((val) => {
    throw new Error('回调函数中错误')
}, (err) => {
    console.log(err, 1);
}).then(null, (err) => {
    console.log(err, 2);//此处捕获,也可用 catch
});

两者不等价的情况:

此时,catch 捕获的并不是 p1 的错误,而是 p2 的错误,

p1().then(res => {
    return p2()//p2 返回一个 promise 对象
}).catch(err => console.log(err))
一个错误捕获的错误用例:
该函数调用中即使发生了错误依然会进入then 中的resolve 的回调函数,因为函数 p1中实例化 promise 对象时已经调用了 catch,若发生错误会进入 catch 中,此时会返回一个新的promise,因此即使发生错误依然会进入 p1 函数的 then 链中的 resolve 回调函数.


function p1(val) {
    return new Promise((resolve, reject) => {
        if (val) {
            var len = val.length;//传入 null 会发生错误,进入 catch 捕获错
            resolve(len);
        } else {
            reject();
        }
    }).catch((err) => {
        console.log(err)
    })
};
p1(null).then((len) => {
    console.log(len, 'resolved');
}, () => {
    console.log('rejected');
}).catch((err) => {
    console.log(err, 'catch');
})
Promise 回调链:
promise 能够在回调函数里面使用 return 和 throw, 所以在 then 中可以 return 出一个promise 对象或其他值,也可以 throw 出一个错误对象,但如果没有 return,将默认返回undefined,那么后面的 then 中的回调参数接收到的将是 undefined.
function p1(val) {
    return new Promise((resolve, reject) => {
        val == 1 ? resolve(1) : reject()
    })
};
function p2(val) {
    return new Promise((resolve, reject) => {
        val == 2 ? resolve(2) : reject();
    })
};
let promimse = new Promise(function (resolve, reject) {
    resolve(1)
})
    .then(function (data1) {
        return p1(data1)//如果去掉 return,则返回 undefined 而不是 p1 的返回值,会导致报错
    })
    .then(function (data2) {
        return p2(data2 + 1)
    })
    .then(res => console.log(res))
Generator 函数:
generator 函数使用:
1、分段执行,可以暂停
2、可以控制阶段和每个阶段的返回值
3、可以知道是否执行到结尾
function* g() {
    var o = 1;
    yield o++;
    yield o++;
}
var gen = g();
console.log(gen.next()); // Object {value: 1, done: false}
var xxx = g();
console.log(gen.next()); // Object {value: 2, done: false}
console.log(xxx.next()); // Object {value: 1, done: false}
console.log(gen.next()); // Object {value: undefined, done: true}
generator 和异步控制:
利用 Generator 函数的暂停执行的效果,可以把异步操作写在 yield 语句里面,等到调用next 方法时再往后执行。这实际上等同于不需要写回调函数了,因为异步操作的后续操作可以放在 yield 语句下面,反正要等到调用 next 方法时再执行。所以,Generator 函数的一个重要实际意义就是用来处理异步操作,改写回调函数。
async 和异步:
用法:
async 表示这是一个 async 函数,await 只能用在这个函数里面。
await 表示在这里等待异步操作返回结果,再继续执行。
await 后一般是一个 promise 对象
示例:async 用于定义一个异步函数,该函数返回一个 Promise。
如果 async 函数返回的是一个同步的值,这个值将被包装成一个理解 resolve 的 Promise,等同于 return Promise.resolve(value)。
await 用于一个异步操作之前,表示要“等待”这个异步操作的返回值。await 也可以用于一个同步的值。
let timer = async function timer() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('500');
        }, 500);
    });
}
timer().then(result => {
    console.log(result); //500
}).catch(err => {
    console.log(err.message);
});
//返回一个同步的值
let sayHi = async function sayHi() {
    let hi = await 'hello world';
    return hi; //等同于 return Promise.resolve(hi);
}
sayHi().then(result => {
    console.log(result);
});





版权声明 : 本文未使用任何知识共享协议授权,您可以任何形式自由转载或使用。

 可能感兴趣的文章

评论区

发表评论 / 取消回复

必填

选填

选填

◎欢迎讨论,请在这里发表您的看法及观点。

«    2023年11月    »
12345
6789101112
13141516171819
20212223242526
27282930

最新留言