promise基础知识(面试题)

语法、promise的两个属性、状态属性的三个值以及规则、then之后的返回值、promise函数同步但是then方法内部代码是异步执行

主要应用是封装ajax操作

Promise是es6引入的异步编程的新的解决方案,通过封装异步操作并可以获取成功或者失败的结果。Promise提供统一的api。Promise对象有两个属性,一个是PromiseState,代表的是状态,一个是PromiseResult,代表的是内容

新建一个promise构造函数,函数接受一个函数作为参数,同时该函数有两个参数,reject和resolve。执行异步操作,成功执行resolve(),状态变成resolved状态;失败执行reject(),状态变成rejected状态。无论成功还是失败都可以通过.then()指定成功和失败的回调函数,catch只能调用失败的回调函数。

promise的三个状态:pending,表示进行中,fulfilled也是resolved,表示成功,rejected,表示失败。只能从pending->resolved或者pending->rejected。构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用,即promise 状态一旦改变则不能再变。

Promise是可以链式回调,而且是可以回调穿透的,回调穿透的意思是可以连续调then方法,只在最后加上catch方法就可以了。

为什么说promise是解决异步编程:在then方法中的内容是异步执行的,即走到then方法之后是可以继续执行和then同级的下编代码,再去执行then里面的代码,所以是实现异步编程。简而言之,执行到then方法之后,不用等到then方法中回调函数执行完毕,就可以继续执行跟then平级的下方的代码。

为什么用promise可以解决异步转同步的问题:Promise函数是同步的,但是then里面的函数是异步的。把promise函数中的resolve或者reject中的代码走完,才会触发then方法中的回调函数。这是promise实现异步转化为同步的关键。简而言之,只有把p函数的内容执行完才能执行then里面的回调。

Promise的语法

Const p = new Promise((resolve,reject) => {

If (true) {

resolve(value)

} else {

reject(err)

}

})

p.then(

Value =>{}

reason=>{}

).catch( )

Console.log(‘222’)
Promise函数是同步的,但是then里面的函数是异步的

注:所谓同步代码,就是这行代码不走完不走下一行,但是异步是不走完这一行,下一行也可以走。

const promise = new Promise((resolve, reject) => {

console.log(1)

resolve()

console.log(2)

})

promise.then(() => {

console.log(3)

})

console.log(4)

运行结果:1 2 4 3
构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用,即promise 状态一旦改变则不能再变。

// 调then方法的时候会走进promise函数,

// 如果如果满足a>4就调用resolve方法,触发then方法的第一个回调函数表示成功

// 如果满足a<4,调用reject方法,触发then方法的第二个回调函数表示失败

// catch方法和触发第二个回调其实是一样的,如果触发then的第二个函数,就不再触发

// catch这个回调了

const promise = new Promise((resolve, reject) => {

const a = 3

if (a > 4) {

resolve('success1')

}

if (a < 4) {

reject('error1')

}

if (a > 4) {

resolve('success2')

}

if (a < 4) {

reject('error2')

}



})

promise.then((res) => {

console.log('then: ', res)

}, (reason) => {

Console.log(‘reason:’, reason)).catch((err) => {

console.log('catch: ', err)

})
/*

执行then方法后也是返回一个promise,这个promise对象的结果取决于then方法中的回调函数

1. 如果是throw '',那么afterThen的结果是一个promise,状态是rejected,内容是throw的值

2. 返回的结果是非promise对象,那么状态是fullfilled,内容是返回的内容

3. 返回的结果是promise对象,那么状态和内容取决于返回的promise对象

*/

const p = new Promise((resolve, reject) => {

resolve('ok')

})

const afterThen = p.then(value => {

// 第一种

const obj = {

code: 500

}

throw obj

// 第二种

// return '哈哈哈哈哈哈'

// 第三种

// const p = new Promise((resolve, reject) => {

// // resolve('返回的是promise对象')

// const obj = { error: 'promise返回的reject内容' }

// reject(obj)

// })

// return p

})

console.log('afterThen', afterThen)



第一种打印结果

第二种打印结果

第三种打印结果

promise1 会一直处于挂起状态,所以 () => {console.log(3);} 不会被执行,控制台也不会输出3。 输出结果:1 4

const promise1 = new Promise((resolve, reject) => {

console.log(1);

});

promise1.then(() => {

console.log(3);

});

console.log(4);
promise函数是同步的,所以先打印出来111和222,走完这之后继续同步执行代码,走到promise.then这一行,继续同步执行代码走到后边两个log那两行。最后走到console.log(res)这一行。

const promise1 = new Promise((resolve, reject) => {

console.log(‘111’)

resolve('resolve1')

console.log('222')

})

const promise2 = promise1.then(res => {

console.log(res)

})

console.log('promise1:', promise1); // 这是一个promise对象,包含状态和resolve的内容

console.log('promise2:', promise2);

输出结果

 

封装ajax操作

onPromiseAjax () {

let p = new Promise((resolve, reject) => {

const xhr = new XMLHttpRequest()

xhr.open('get', 'http://127.0.0.1:8263/todo')

xhr.send()

xhr.onreadystatechange = function () {

if (xhr.readyState === 4) {

if (xhr.status === 200) {

resolve(xhr.response)

} else {

reject(xhr.status)

}

}

}

})

console.log('p-->>', p)

p.then(value => {

console.log(value)

}, reason => {

console.log(reason)

})

},
// 异步转同步第一种:将一个函数当作另一个主函数的参数来使用的函数

// 执行完changeOne函数后再执行changeTwo函数

change () {

this.changeOne(this.changeTwo)

},

changeOne (callback) {

console.log('执行了changeOne') // changeOne的所有代码逻辑,也可以有很多行

callback()

},

changeTwo () {

console.log('执行了changeTwo')

},

// 异步转同步第二种:将先执行的函数作为一个promise进行使用

// 原理:promise函数是一个同步函数,需要先把promise函数内部的代码走完,

// 才会执行then里面的代码。即把resolve的代码走完(成功这种情况)才会触发then

// 方法下的第一个成功的回调。从而实现同步转为异步

// 执行完onSubmitToServer再执行onSkip函数

hello () {

this.onSubmitToServer().then(() => {

this.onSkip()

})

},

onSubmitToServer () {

return new Promise((resolve) => {

resolve(

console.log('执行了第一个方法onSubmitToServer的内容')

)

})

},

onSkip () {

console.log('执行了第二个方法onSkip的内容')

},

// 第三种通过async和await方法

// async和await是配套使用的,await必须写在async函数的内部

// await只能处理Promise对象的异步等待(别的setTimeout,load等造成的异步不能被处理,如果这些异步也想要被处理成同步等待,只能放在Promise里面)

readSync () {

return new Promise((resolve) => {

resolve(

console.log('执行readSync方法'),

console.log('执行readSync方法--again')

)

})

},

async readAsync () {

// 调用异步方法

await this.readSync()

// 异步等待 同步执行:需要把readSync方法内部的走完才会走下边的js代码

console.log('执行readAsync方法')

console.log('end ...')

}

猜你喜欢

转载自blog.csdn.net/bukuaileya/article/details/128550845