promise
what is it
From an abstract point of view, it is a new solution. is JS
the solution for asynchronous programming in Solve. The old solution is: pure callback (but promise
there is also a callback function in it, so I added one 纯
), so there is a callback hell.
Grammatically speaking: Promise
it is a constructor. So you can create an instance object, and then direct the instance object to do things. On the contrary, if it is a general function, it is the function itself to do things.
In terms of function: promise
the object is used to encapsulate an asynchronous operation and can obtain its result
promise
The status changes for:
pending
becomesresolved
pending
becomesrejected
- Only these 2 states
pending
Indicates the initialization state- And an
promise
object can only be changed once - Whether it becomes success or failure, there will be a result data
- The successful result data is generally called
vlaue
, and the failed result data is generally calledreason
promise
The basic process of:
describe:
- Create a new object, and the state of the
promise
newly created object is the state, that is, the initialization statepromise
peding
promise
Pass a parameter to the constructor, which is the parameter执行器函数
, and执行器函数
execute the asynchronous task in- Executing asynchronous tasks may eventually succeed or fail. If it succeeds,
resolve()
the method is executed, andpromise
the state of the object becomesresolved
the state; if it fails,reject()
the method is executed, andpromise
the state of the object becomesrejected
the state. - After the state changes, call the success or failure callback function
- The callback function for success or failure is passed
.then
or.catch
specified. Among them,.then
you can specify both a successful callback and a failed callback; but.catch
you can only specify a failed callback - Finally, a new object
.then
is returnedpromise
The basic use of Promise:
Why Promises
Pure callback: When you actually execute an asynchronous task 之前
, you have to 事先
specify the callback function, that is, you must first specify the callback function, and then start the asynchronous task, and it must be like this.
promise
Object: You can specify the callback function after the asynchronous task is started, but you can specify the callback function before the asynchronous task succeeds or has a result. Of course, you can also specify it after the asynchronous task has a result. This is also something that pure callbacks cannot do. That is, compared with pure callback functions, promise
objects are more flexible in the way of specifying callback functions.
Summary:promise
The way to specify the callback function is more flexible. Generally, the callback function is specified after the asynchronous task is executed.
纯回调
: must be specified before starting the asynchronous task
Promise
The constructor itself receives an executor function excutor
, and the executor function excutor
receives two functions, one is resolve
a function and the other is reject
a function. And the executor function excutor
is a synchronous callback function, and the real asynchronous code is written in the executor function excutor
.
Promise
The prototype object of has a then
method that specifies two parameters onResolved, onRejected
, both of which are function types. More precisely, it is a callback function, one corresponding to the success callback, and one corresponding to the failure callback. The successful callback receives value
, and the failed callback receives reason
, and returns a new promise
object. This is also promise
the prerequisite for chain calls.
promise
Chain calls are supported, so the problem of callback hell can be solved.
What is Callback Hell?
Answer: The callback function is called nestedly, and the result of the asynchronous execution of the external callback function is the condition for the execution of the nested callback function. Callback hell involves multiple asynchronous operations, and it's executed serially . What is tandem execution? Suppose there are asynchronous task 1, asynchronous task 2, asynchronous task 3..., where the second asynchronous task is conditioned on the result of the first asynchronous task, and similarly, the third asynchronous task is conditioned on the result of the second asynchronous task. At this time, nesting of callbacks will occur, and the code organization form will gradually move to the right. This kind of code is difficult to read. Then the exception handling has to be dealt with separately, which will also increase the difficulty of handling. This kind of follow-up processing is troublesome, and the situation of unchanged reading is callback hell.
Every time an promise
object is obtained, it means that an asynchronous task has been started, or one promise
corresponding to an asynchronous task. Then .then
the coding method is executed from top to bottom, similar to synchronous coding, it is not in a nested form, and there will be no callback hell. Then, in the way of handling exceptions, it only needs to be processed at the end, that is, only some successful callbacks are needed in the middle.
//2.2. 使用promise的链式调用解决回调地狱
doSomething()
.then(function(result) {
return doSomethingElse(result)
})
.then(function(newResult) {
return doThirdThing(newResult)
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult)
})
.catch(failureCallback)
The way of handling exceptions at the end is also called exception transmission : in chain calls, there are multiple promise
processes, and no matter what happens to any one, it will be passed layer by layer to the bottom error callback processing.
Summary:promise
Processing is from top to bottom in coding, and reading is more convenient, and exception handling is also more convenient. However, promise
it is not the most optimal choice to solve the callback hell, because promise
there will still be callback functions in , although there is no nesting of callbacks, there will still be callback functions. However, with async
and await
there is no callback function generated.
Q: Disadvantages of Callback Hell?
Answer: Not easy to read / not easy to handle exceptions
Q: Solution?
Answer: promise
chain call
Q: Ultimate solution?
Answer: async
/await
-
Promise
Constructor: Promise (excutor) {}
excutor
Executor function: synchronous execution (resolve, reject) => {}
resolve
function: the function we call when the internal definition succeeds value => {} function
reject
: the function we call when the internal definition fails reason => {}
Note: the synchronous callbackexcutor
will bePromise
executed internally, while the asynchronous operation is executed in the executor -
Promise.prototype.then
Method: (onResolved, onRejected) => {}
onResolved
Function: Successful callback function (value) => {}
onRejected
Function: Failure callback function (reason) => {}
Explanation: Specify the success callback for obtaining the successful value, and the failure callback for obtaining the failure reason, and return a new promise object, which is also the prerequisite forpormise
supporting chain calls. -
Promise.prototype.catch
Method: (onRejected) => {}
onRejected
Function: Failed callback function (reason) => {}
Description:then()
Syntactic sugar, equivalent to:then(undefined, onRejected)
-
Promise.resolve
Method: (value) => {}
value: successful data orpromise
object
Description: Returns a success/failurepromise
object, which is essentially syntactic sugar.
//二者都返回一个promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 100);
})
const p2 = Promise.resolve(2)
Promise.reject
Method: (reason) => {}
reason
: Reason for failure
Description: Returns a failed promise object, which is essentially syntactic sugar.
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(1)
}, 100);
})
const p3 = Promise.reject(3)
Promise.all
method: (promises) => {}
promises
:n
arraypromise
containing
Description: Return a new one promise
, only if all of promise
them succeed, it will succeed, as long as one of them fails, it will fail directly
const pAll = Promise.all([p1, p2])
pAll.then(
//注意,此次的value是个复数,也就是说最后输出的 values 是个数组,起里面值的顺序和all里面promise数组一致,和执行完成的先后顺序没有关系,不过用Promise.race时,和执行完成的先后顺序有关系
values => {
console.log('all onResolved()', values)
},
reason => {
console.log('all onRejected()', reason)
}
)
Promise.race
Method: (promises) => {}
promises
: containsn
anpromise
array
Description: Return a new onepromise
, the first completedpromise
result state is the final result state
//根据race这个单词的意思可知,这个方法更强调的是谁先完成,我就先返回它的值
const pRace = Promise.race([p1, p2, p3])
pRace.then(
value => {
console.log('race onResolved()', value)
},
reason => {
console.log('race onRejected()', reason)
}
)
Callback function: you define; you don't call it yourself; but it is executed in the end
Promise several key issues
- How to change the state of promise?
- resolve(value): If it is currently pending, it will become resolved
- reject(reason): If it is currently pending, it will become rejected
- Throw an exception: If it is currently pending, it will become rejected
const p = new Promise((resolve, reject) => {
// resolve(1) // promise变为resolved成功状态
// reject(2) // promise变为rejected失败状态
// throw new Error('出错了') // 抛出异常, promse变为rejected失败状态, reason为 抛出的error
throw 3 // 抛出异常, promse变为rejected失败状态, reason为 抛出的3
})
p.then(
value => {
},
reason => {
console.log('reason', reason)}
)
p.then(
value => {
},
reason => {
console.log('reason2', reason)}
)
- Will one
promise
specify multiple success/failure callback functions, will they all be called?
Answer: Yes. However, there are conditions, that is, when promise
changing to the corresponding state 都会调用
.
- Who should change the promise state and specify the callback function first?
Answer: Both are possible. Under normal circumstances, the callback is specified first and then the state is changed, but it is also possible to change the state first and then specify the callback.
-
How to change the state first, and then specify the callback?
①Call resolve()/reject() directly in the executor
②Delay for a longer time before calling then()
new Promise((resolve, reject) => { resolve(1) //先改变的状态(同时指定数据) }).then(// 后指定回调函数, 异步执行回调函数 value => { console.log('value2', value)}, reason => { console.log('reason2', reason)} ) //验证 .then 里面的回调函数是同步执行,还是异步执行,结果:异步执行 //即,执行器函数里面的 resolve(1)和 .then 都是同步执行,而 .then 里面的 value和 reason 回调函数都是异步执行 console.log('-------')
Summary:
promise
Yes, the callback function, whether it is success or failure, is always executed asynchronously. Even if the condition has been met, that is, the state has changed, it will not be executed immediately. -
How to specify the callback function first, and then change the state? conventional
// 常规: 先指定回调函数, 后改变的状态 new Promise((resolve, reject) => { setTimeout(() => { resolve(1) // 后改变的状态(同时指定数据), 异步执行回调函数 }, 1000); }).then(// 先指定回调函数, 保存当前指定的回调函数 value => { }, reason => { console.log('reason', reason)} )
-
When will the data be available?
①If the callback is specified first, then when the state changes, the callback function will be called to get the data
②If the state is changed first, then when the callback is specified, the callback function will be called to get the data
promise.then()
promise
What determines the new result status returned ? (This is the most important)
(1) Simple expression: determined by the execution result of the callback function specified by then()
(2) Detailed expression:
①If an exception is thrown, the new promise becomes rejected
,
and reason is the thrown exception
new Promise((resolve, reject) => {
// resolve(1)
reject(1)
}).then(
value => {
console.log('onResolved1()', value)
// return 2
// return Promise.resolve(3)
// return Promise.reject(4)
throw 5
},
reason => {
console.log('onRejected1()', reason)
// return 2
// return Promise.resolve(3)
// return Promise.reject(4)
throw 5
}
).then(
value => {
console.log('onResolved2()', value)
},
reason => {
console.log('onRejected2()', reason)
}
)
promise
How to connect multiple operation tasks in series? (It may be a synchronous task or an asynchronous task)
Answer: (1) promise
Returning then()
a new one promise,
can be regarded as then()
a chained call
(2) then
Chaining multiple synchronous or asynchronous tasks through the chained call. However, if it is asynchronous, it must be wrapped inpromise
it, because promise
it is used to encapsulate asynchronous operations . (See the second .then
internal asynchronous task for details)
new Promise((resolve, reject) => {
resolve(1)
}).then(
value => {
console.log('onResolved1()', value)
return 2 //同步操作
},
).then(
value => {
console.log('onResolved12()', value)
return new Promise((resolve,reject) =>{
//注意:这是一个异步任务,所以必须用promise来封装
setTimeout(() =>{
resolve(3)
},1000)
})
},
).then(
value => {
console.log('onResolved3()', value)
},
)
})
Note: When promise
connecting multiple operation tasks in series, promise.then()
the callback function type in the first one will not affect promise.then()
the callback function in the second one. It can only affect the callback function in the second one promise.then()
, but it can only be the return valuepromise.then()
of the callback function in the first one .
For example:
new Promise((resolve, reject) =>{
resolve(1)
}).then(
reason =>{
return 2
}
).then(
value =>{
console.log(value)
},
reason =>{
console.log(reason)
}
)
Observe the above code: in the first .then()
one, the failed callback function is executed onrejected
, but its return value is not 异常
( throw
, or return Promise.resolve()
), that is, although the failed callback is executed, the successful callback.then
is executed in the next one .
promise
Exception transmission/penetration?
(1) When using promise
chain then
calls, you can specify the failed callback at the end,
(2) Any exception in the previous operation will be passed to the last failed callback for processing
- Broken
promise
chain?
(1) When the chain call is used promise
, then
it will be interrupted in the middle, and the subsequent callback function will not be called (2) Method: return a state object
in the callback functionpendding
promise
return new Promise(() => {
}) // 返回一个pending的promise 中断promise链
Supplement:=>
There is a function in the arrow function : return
, the premise is that =>
there is no{}