Promise chain call, exception penetration and interrupt promise chain

promise. Parameters of then()

. then is a method on promise prototype, which returns a promise object, which can accept two callback parameters: 1 onResolved, 2. Onrejected, these two parameters have one parameter respectively, which is the data of successful execution and the data of failed execution. In fact, the first callback function we usually use most is to process the data after the request is successful. For example:

new Promise((resolve, reject) => {
	resolve('succeed');
}).then((data) => {
	// The data here is the value received by resolve after the asynchronous request succeeds
	console.log('success: ', data); // output: success
})

But in fact, it also has a second callback function to process the data in case of failure:

new Promise((resolve, reject) => {
	reject('success');
}).then(
(data) => {	console.log('success: ', data);},
(err) => { console.log('failed: ', err);}
)

promise chained call

Chain call, last time The data processed by then() becomes undefined?

Let's take a look at this example:

new Promise((resolve, reject) => {
	resolve('succeed')
	// reject('failed ')
})
	.then(
		(data) => { console.log('onResolved1', data);},
		(error) => { console.log('onRejected1', error);}
	)
	.then(
		(data) => { console.log('onResolved2', data);},
		(error) => { console.log('onRejected2', error);}
	)

↑ what results will be printed on it?
Can it be 'onResolved1', 'succeeded', 'onResolved2', 'succeeded'?

You'll find it in the second In then(), although the callback for successful processing is also taken, the data is lost and becomes undefined
Explain the previous one The promise object returned by then() must have lost its data. We can print this promise again:

It is not difficult to see that the result here has indeed become undefined, so that when the chain call, the next one then() can't get the result
In fact, the essential reason is: if you want to chain call, then the previous one The callback function for processing data in then() must have a return value (whether onResolved or onRejected), otherwise the data will be lost and the next one will be executed by default onResolved callback in then!
When we return, there are two cases (fixed value / promise):

// Write directly The then section:
.then(
	(data) => {
		console.log('onResolved1', data)
		// Case 1: return fixed value
		return 'success'
		// Case 2: return promise
		return new Promise((resolve, reject) => {
			resolve(data)
		})
	},
)
.then(
  (data) => { console.log('onResolved2', data)},
  (error) => { console.log('onRejected2', error)}
)

The above two cases can be executed normally. Let the next one The callback function in then() gets the value:

How to according to the previous one Then decided to carry out the next Callback in then?

since. There are two callbacks in then(). How do I know whether to handle the successful or failed callbacks in the chain call?

// Execution now failed:
const p = new Promise((resolve, reject) => {
  reject('failed')
}).then(
  (data) => { console.log('onResolved1', data)},
  (error) => {
  	// Scenario 1: no return
    console.log('onRejected1', error)
    // Scenario 2: return fixed value
    return 'failed'
    // Scenario 3: return promise reject
    return Promise.reject(error)
    // Scenario 4: return promise resolve
    return Promise.resolve(error)
    // Scenario 5: throw error:
    throw error;
  }
)
p.then(
  (data) => { console.log('onResolved2', data)},
  (error) => { console.log('onRejected2', error)}
)

You will find:

the previous. Return value of thennext. then's execution results
return undefinedPerform onResolved
return fixed valuePerform onResolved
return Promise.resolvePerform onResolved
return Promise.rejectExecute onRejected
throw dataExecute onRejected

That is, the last one The difference in the return value of the callback function in then determines the next Then performs different callbacks. (in other words, it has nothing to do with which callback the last. Then executed, but only with its return value)

promise exception penetration

Of course, as the parameter of then mentioned at the beginning, in In then(), we often pass onResolved to process the successful data. Generally, onRejected is not passed in then, but the failed data is usually placed at the end In catch():

// Execution now failed:
new Promise((resolve, reject) => {
  reject('failed')
}).then(
  (data) => { console.log('onResolved1', data)},
).then(
  (data) => { console.log('onResolved2', data)},
).then(
  (data) => { console.log('onResolved3', data)},
).catch(
  (err) => { console.log('onRejected1', data)},
)

In the above example, the failed data is received at the beginning of reject, and the data will eventually pass The callback function in catch is used for processing, but what I want to explain here is that the failed data is directly entered at once Catch?
Obviously not. Since it is a chain call, it must be passed through layer by layer, but in There is no callback for processing failed data in then(), why does it pass down normally?
Actually, when we're here In then(), when the second parameter is not written, the default is as follows:

.then(
(data) => { ...handle data },
// If you do not write the second parameter, it is equivalent to passing it by default:
(err) => Promise.reject(err), 
// or
(err) => { throw err; }
).then()

This is why chained calls can be written at the end The reason why catch() can still get data

How to interrupt promise

If you wait until the end After the catch() is processed, if you want to end the promise chain, you don't want to call it in a chain. You can do the following:

.catch((err) => {
  console.log('onRejected', err);
  // Interrupt promise chain:
  return new Promise(() => {})
})

By returning a status that has been pending.

Keywords: Javascript Front-end ECMAScript

Added by dodgeqwe on Fri, 31 Dec 2021 06:52:55 +0200