This is the second day of my participation in the August Text Challenge.More challenges in August

1. Prepare knowledge

1.1 Instance objects and function objects

  • Instance objects: Objects generated by the new function are called instance objects, or objects for short
  • Function objects: When functions are used as objects, they are called function objects
function Fn() { // Fn can only be called a function
}
const fn = new Fn() // Fn can only be called a constructor if it is new
//fn is called the instance object
console.log(Fn.prototype)// Fn can only be called a function object if it is used as an object
Fn.bind({}) //Fn is used as a function object
$('#test') // $as a function
$.get('/test') $is used as a function object
Copy the code

() On the left are functions. On the left are objects (function objects, instance objects).

1.2 Two types of callback functions

1. Synchronize the callback

Execute immediately, complete, and not put into the callback queue

Array traversal of the associated callback/Promise executor function

const arr = [1.3.5];
arr.forEach(item= > { // The loop callback is not queued, and is executed immediately
  console.log(item);
})
console.log('the forEach ()')
Copy the code

2. Asynchronous callback

It will not be executed immediately and will be placed in the callback queue for future execution

Timer callback, Ajax callback, and Promise success or failure callback

// Timer callback
setTimeout(() = > { // An asynchronous callback is queued for future execution
  console.log('timeout callback()')},0)
console.log('the setTimeout ()')
Copy the code

// Promise a successful or failed callback
new Promise((resolve, reject) = > {
  resolve(1)
}).then(
  value= > {console.log('value', value)},
  reason= > {console.log('reason', reason)}
)
console.log(The '-')
// ----
// value 1
Copy the code

The js engine executes the code in the callback queue after completing the initial synchronization

1.3 Error handling in JS

1. Wrong type

Error: Parent type of all errors

ReferenceError: The variable referenced does not exist

console.log(a) // ReferenceError:a is not defined
Copy the code

TypeError: Indicates that the data type is incorrect

let b
console.log(b.xxx)
// TypeError:Cannot read property 'xxx' of undefined

let c = {}
c.xxx()
// TypeError:c.xxx is not a function
Copy the code

RangeError: Data values are not in the range allowed

function fn() {
  fn()
}
fn()
// RangeError:Maximum call stack size exceeded
Copy the code

SyntaxError: indicates a SyntaxError

const c = """"
// SyntaxError:Unexpected string
Copy the code

2. Error handling (catch and throw)

Throw error: Throw error

function something() {
  if (Date.now()%2= = =1) {
    console.log('The current time is odd, the task can be performed')}else { // Throw an exception if the time is even, handled by the call
    throw new Error('Current time is even, task cannot be performed')}}Copy the code

Catch error: try… catch

// Catch and handle exceptions
try {
  something()
} catch (error) {
  alert(error.message)
}
Copy the code

3. Error object

  • Massage attribute: error related information
  • Stack property: Function call stack record information
try {
  let d
  console.log(d.xxx)
} catch (error) {
  console.log(error.message)
  console.log(error.stack)
}
console.log('After the error')
// Cannot read property 'xxx' of undefined
// TypeError:Cannot read property 'xxx' of undefined
// After the error
Copy the code

Because the error is caught and handled, the following code can run, printing ‘after the error’

2. Understanding and use of Promise

2.1 What is Promise

1. Understand the Promise

  • Abstract expression

Promise is a new solution to asynchronous programming in JS (the old solution was simply to use callback functions)

Async and Async – Async and Parallelism – Async and Parallelism – Async and Callbacks – Callback hell – Async operations in JavaScript

—- asynchronous programming ① FS file operation ② database operation ③Ajax ④ timer

  • The specific expression of

A Promise is a constructor (all, reject, resolve, then, catch, etc.).

② Functionally, the Promise object encapsulates an asynchronous operation and can obtain its success/failure result value

  • Ruan Yifeng explains

A Promise is simply a container that holds the result of some event that will end in the future (usually an asynchronous operation). Syntactically, a Promise is an object from which messages for asynchronous operations can be retrieved. Promises provide a unified API, All kinds of asynchronous operations can be handled in the same way

2. Promise status

PromiseState, a property of the instance object promise

  1. pendingintoresolved/fullfilled
  2. pendingintorejected

Pay attention to

  • The status of an object is not affected
  • There are only two, and onepromiseThe object can only change once
  • Once the state changes, it never changes again, and you can get this result at any time
  • Success or failure, there will be a result data. Successful outcome data is commonly calledvalueAnd failure is commonly calledreason.

3. Value of the Promise object

The other value of the instance object promise, PromiseResult, holds the success/failure value of the object (value/reason).

Resolve /reject you can change the value

4. Basic process of Promise

5. Basic use of Promises

const promise = new Promise(function(resolve, reject) {
  // ... some code
  if (/* Asynchronous operation succeeded */){
    resolve(value);
  } else{ reject(reason); }});Copy the code

The Promise constructor takes a function (the executor function) as an argument, resolve and reject. They are two functions that are provided by the JavaScript engine and do not need to be deployed themselves.

The resolve function changes the state of the Promise object from “unfinished” to “successful” (that is, from pending to Resolved), calls it when the asynchronous operation succeeds, and passes the result of the asynchronous operation as value. The Reject function changes the state of the Promise object from “unfinished” to “failed” (i.e., from Pending to Rejected). The reject function is called when the asynchronous operation fails and passes the errors reported by the asynchronous operation as error/ Reason.

After the Promise instance is generated, you can use the THEN method to specify the resolved and Rejected state callback functions, respectively.

promise.then(function(value) {
  // success
}, function(reason) {
  // failure
});
Copy the code

The then method can take two callback functions as arguments. The first callback, onResolved(), is called when the Promise object’s state changes to Resolved. The second callback, onRejected(), is called when the Promise object’s state changes to Rejected. These two functions are optional and do not have to be provided. They all accept the value passed out from the Promise object as an argument

  • A case in point
// Create a new P object Promise
const p = new Promise((resolve, reject) = > { // The executor function
  // Perform asynchronous operation tasks
  setTimeout(() = > {
    const time = Date.now() 
    // If the current time is even, success, otherwise failure
    if (time % 2= =0) {
      // Call resolve(value) if successful
      resolve('Successful data, time=' + time)
    } else {
      Reject (reason)
      reject('Failed data, time=' + time)
    }
  }, 1000);
})

p.then(
  value= > { // Successfully receive value data onResolved
    console.log('Successful callback', value)  Successful callback data, time=1615015043258
  },
  reason= > { // Receive the failed Reason data onRejected
    console.log('Failed callback', reason)    // Failed callback failed data, time=1615014995315})Copy the code

.then() and executor are executed synchronously, and callbacks in.then() are executed asynchronously

2.2 Why use Promise

1. More flexibility in the way callback functions are specified

Old: Must be specified before starting asynchronous tasks

// 1. Pure callback form
// Successful callback function
function successCallback(result) {
  console.log("Sound file created successfully: + result);
}
// Failed callback function
function failureCallback(error) {
  console.log("Sound file creation failed:" + error);
}
// The callback function must be specified before the asynchronous task is executed
createAudioFileAsync(audioSettings, successCallback, failureCallback) The callback function is specified before the asynchronous task (function) is executed
Copy the code

Promise: Start the asynchronous task => return the Promise object => Bind the callback function to the Promise object (you can even specify it after the asynchronous task ends)

// 2. Use Promise
const promise = createAudioFileAsync(audioSettings);  // Run for 2 seconds
setTimeout(() = > {
  promise.then(successCallback, failureCallback) // Also available
}, 3000);
Copy the code

For details, refer to 03Promise. HTML is basically used. 04 Why use promise.html

2. Support chain call, can solve the problem of callback hell

What is callback hell?

Callback functions are nested calls, and the result of the asynchronous execution of the external callback function is a condition for the execution of its internal nested callback function

doSomething(function(result) {
  doSomethingElse(result, function(newResult) {
    doThirdThing(newResult, function(finalResult) {
      console.log('Got the final result:' + finalResult)
    }, failureCallback)
  }, failureCallback)
}, failureCallback)
Copy the code
Callback to hell’s shortcomings?
  1. Unreadable
  2. Not convenient for exception handling
The solution?
  • Promise chain call

Use Promise’s chain calls to solve callback hell

doSomething()
  .then(result= > doSomethingElse(result))
  .then(newResult= > doThirdThing(newResult))
  .then(finalResult= > {console.log('Got the final result:' + finalResult)})
  .catch(failureCallback)
Copy the code
The ultimate solution?
  • async/await

The ultimate solution to callback hell async/await

async function request() {
  try{
    const result = await doSomething()
    const newResult = await doSomethingElse(result)
    const finalResult = await doThirdThing(newResult)
    console.log('Got the final result:' + finalResult)
  } catch (error) {
    failureCallback(error)
  }
}
Copy the code

2.3 How do I Use Promise

1. Promise constructor:Promise(executor) {}

  • Executor functions: Synchronize execution (resolve, reject) => {}

  • Resolve function: internally defined function resove(value) to be called on success

  • Reject function: Call reject(reason) when internal definition fails

Note: Executor is the executor that immediately synchronizes the callback within the Promise, and the asynchronous resolve/ Reject operation is performed within executor

2. Promise.prototype. Thenp.then(onResolved, onRejected)

Specify two callbacks (success + failure)

  • OnResolved function: Successful callback (value) => {}

  • OnRejected () => {}

Note: Return a new Promise object by specifying a success callback for a success value and a failure callback for a failure Reason

3. Prototype. Catch method:p.catch(onRejected)

Specify a failed callback

1) onRejected () => {}

A: Yes, it is (), onRejected.

new Promise((resolve, reject) = > { // the excutor executor function
 setTimeout(() = > {
   if(...). { resolve('Success data') / / the resolve () function
   } else { 
     reject('Failed data') / / reject () function}},1000)
}).then(
 value= > { / / onResolved () function
  console.log(value) // Success data
}
).catch(
 reason= > { / / onRejected () function
  console.log(reason) // Failed data})Copy the code

4. Promise. ResolvePromise.resolve(value)

Value: The parameter that will be resolved by the Promise object, which can also be a successful or failed Promise object

Return: Returns a parsed Promise object with the given value, or if the argument itself is a Promise object, the Promise object is returned.

  1. If the argument passed is an object of type other than a Promise, the result returned is a successful Promise object
let p1 = Promise.resolve(521);
console.log(p1); // Promise {<fulfilled>: 521}
Copy the code

  1. If the argument passed in is a Promise object, the result of the argument determines the result of resolve
let p2 = Promise.resolve(new Promise((resolve, reject) = > {
    // resolve('OK'); // The Promise of success
    reject('Error');
}));
console.log(p2);
p2.catch(reason= > {
    console.log(reason);
})
Copy the code

5. Promise. RejectPromise.resolve(reason)

Reason: Indicates the reason for the failure

Description: Returns a failed Promise object

let p = Promise.reject(521);
let p2 = Promise.reject('iloveyou');
let p3 = Promise.reject(new Promise((resolve, reject) = > {
    resolve('OK');
}));

console.log(p);
console.log(p2);
console.log(p3);
Copy the code

  • The promise.resolve ()/ promise.reject () method is a syntactic sugar
  • Used to get Promise objects quickly
// Produces a Promise object with a success value of 1
new Promise((resolve, reject) = > {
 resolve(1)})/ / equivalent to
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)

p1.then(value= > {console.log(value)}) / / 1
p2.then(value= > {console.log(value)}) / / 2
p3.catch(reason= > {console.log(reason)}) / / 3
Copy the code

6. Promise.Promise.all(iterable)

Iterable: An iterable containing n promises, such as Array or String

Note: Return a new promise, which succeeds only if all promises succeed, or if one fails

let p1 = new Promise((resolve, reject) = > {
  resolve('OK');
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Oh Yeah');

const result = Promise.all([p1, p2, p3]);
console.log(result);
Copy the code

let p1 = new Promise((resolve, reject) = > {
  resolve('OK');
})
let p2 = Promise.reject('Error');
let p3 = Promise.resolve('Oh Yeah');

const result = Promise.all([p1, p2, p3]);
console.log(result);
Copy the code

const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)

const pAll = Promise.all([p1, p2, p3])
const pAll2 = Promise.all([p1, p2])
// pAll fails because p3 is failed
pAll.then(
value= > {
   console.log('all onResolved()', value)
 },
reason= > {
   console.log('all onRejected()', reason) 
 }
)
// all onRejected() 3
pAll2.then(
values= > {
   console.log('all onResolved()', values)
 },
reason= > {
   console.log('all onRejected()', reason) 
 }
)
// all onResolved() [1, 2]
Copy the code

7. Promise. Race method:Promise.race(iterable)

Iterable: An iterable containing n promises, such as Array or String

Note: Return a new promise. The result state of the first completed promise is the final result state. Whoever completes it first (whether it succeeds or fails) will be output.

const pRace = Promise.race([p1, p2, p3])
// Output whoever completes first (success or failure)
const p1 = new Promise((resolve, reject) = > {
 setTimeout(() = > {
   resolve(1)},1000)})const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)

pRace.then(
value= > {
   console.log('race onResolved()', value)
 },
reason= > {
   console.log('race onRejected()', reason) 
 }
)
//race onResolved() 2
Copy the code
let p1 = new Promise((resolve, reject) = > {
  setTimeout(() = > {
      resolve('OK');
  }, 1000);
})
let p2 = Promise.resolve('Success');
let p3 = Promise.resolve('Oh Yeah');

/ / call
const result = Promise.race([p1, p2, p3]);

console.log(result);
Copy the code

3. Key Promise questions

1. How to change the state of promise?

(1) Resolve (value) : Resolved if it is pending

(2) Reject (reason) : If it is pending, it changes to Rejected

(3) Raise exception: If the value is pending, it changes to Rejected

const p = new Promise((resolve, reject) = > {
  // Resolve (1) // Promise becomes resolved
  // Reject (2) // The promise changes to rejected
  throw new Error('Wrong') // Raise an exception. Promise changes to rejected. Reason is an error raised
})
p.then(
  value= > {},
  reason= > {console.log('reason',reason)}
)
// Reason Error: There is an Error
Copy the code

2. Will multiple success/failure callbacks specified by a promise be called?

This is called whenever a promise changes to the corresponding state

const p = new Promise((resolve, reject) = > {
  //resolve(1)
  reject(2)
})
p.then(
  value= > {},
  reason= > {console.log('reason',reason)}
)
p.then(
  value= > {},
  reason= > {console.log('reason2',reason)}
)
// reason 2
// reason2 2
Copy the code

3. Which comes first, changing the promise state or specifying the callback function?

Either is possible. The general rule is to specify a callback and then change the state, but you can change the state and then specify a callback

  • How do I change state and then specify a callback?

(1) Call resolve()/reject()

(2) Delay longer before calling then()

let p = new Promise((resolve, reject) = > {
  // setTimeout(() => {
      resolve('OK');
  / /}, 1000); If asynchrony exists, specify the callback first, otherwise change the state first
});

p.then(value= > {
  console.log(value);
},reason= >{})Copy the code
  • When will we get the data?

(1) If the callback is specified first, the callback function will be called to retrieve the data when the state changes

(2) If the state is changed first, the callback function will call the data when the callback is specified

new Promise((resolve, reject) = > {
  setTimeout(() = > {
    resolve(1) // Change the state
  }, 1000)
}).then( // Specify the callback function (first)
  value= > {},
  reason= >{})Copy the code

In this case, specify a callback function and save the currently specified callback function. Then change the state (specifying the data), and execute the previously saved callback asynchronously.

new Promise((resolve, reject) = > {
  resolve(1) // Change the state
}).then( // Specify the callback function
  value= > {},
  reason= >{})Copy the code

In this way, the state is changed (and the data is specified), and the callback function is specified (no further saving is required), and the callback function is executed asynchronously

4. What determines the result state of the new promise returned by promise.then()?

(1) Simple expression: the result of the execution of the callback function specified by then()

let p = new Promise((resolve, reject) = > {
  resolve('ok');
});
// Execute the then method
let result = p.then(value= > {
  console.log(value);
}, reason= > {
  console.warn(reason);
});

console.log(result);
Copy the code

(2) Detailed expression:

(1) If an exception is raised, the new promise changes to Rejected. Reason is the exception raised

let p = new Promise((resolve, reject) = > {
  resolve('ok');
});
// Execute the then method
let result = p.then(value= > {
  //1. Throw an error
  throw 'Something is wrong';
}, reason= > {
  console.warn(reason);
});

console.log(result);
Copy the code

② If any non-PROMISE value is returned, the new promise becomes resolved and value is the returned value

let p = new Promise((resolve, reject) = > {
  resolve('ok');
});
// Execute the then method
let result = p.then(value= > {
	//2. Return a non-PROMISE object
	return 521;
}, reason= > {
  console.warn(reason);
});

console.log(result);
Copy the code

③ If another new promise is returned, the result of that promise becomes the result of the new promise

let p = new Promise((resolve, reject) = > {
  resolve('ok');
});
// Execute the then method
let result = p.then(value= > {
	//3. Return a Promise object
	return new Promise((resolve, reject) = > {
		// resolve('success');
		reject('error');
	});
}, reason= > {
  console.warn(reason);
});

console.log(result);
Copy the code

new Promise((resolve, reject) = > {
  resolve(1)
}).then(
  value= > {
    console.log('onResolved1()', value)
  },
  reason= > {
    console.log('onRejected1()', reason)
  }
).then(
  value= > {
    console.log('onResolved2()', value)
  },
  reason= > {
    console.log('onRejected2()', reason)
  }
)
// onResolved1() 1
// onResolved2() undefined
Copy the code
new Promise((resolve, reject) = > {
  resolve(1)
}).then(
  value= > {
    console.log('onResolved1()', value)
    //return 2 // onResolved2() 2
    //return Promise.resolve(3) // onResolved2() 3
    //return Promise.reject(4) // onRejected2() 4
    //throw 5 // onRejected2() 5
  },
  reason= > {
    console.log('onRejected1()', reason)
  }
).then(
  value= > {
    console.log('onResolved2()', value)
  },
  reason= > {
    console.log('onRejected2()', reason)
  }
)
// onResolved1() 1
// onResolved2() undefined
// Promise {<fulfilled>: undefined}
// The corresponding output is shown above
Copy the code

5. How does promise string together multiple action tasks?

(1) Promise’s then() returns a new promise, which can be combined into a chain call of then()

(2) Concatenate multiple synchronous/asynchronous tasks through chain calls to THEN

let p = new Promise((resolve, reject) = > {
  setTimeout(() = > {
      resolve('OK');
  }, 1000);
});

p.then(value= > {
  return new Promise((resolve, reject) = > {
      resolve("success");
  });
}).then(value= > {
  console.log(value); // success
}).then(value= > {
  console.log(value); // undefined
})
Copy the code

new Promise((resolve, reject) = > {
  setTimeout(() = > {
    console.log('Perform Task 1(asynchronous)')
    resolve(1)},1000)
}).then(
  value= > {
    console.log('Result of Task 1', value)
    console.log('Perform Task 2(Synchronize)')
    return 2 // The synchronization task directly returns the result
  }
).then(
  value= > {
    console.log('Results of Task 2', value)
    return new Promise((resolve, reject) = > { // Asynchronous tasks need to be wrapped in Promise objects
      setTimeout(() = > {
        console.log('Perform Task 3(asynchronous)')
        resolve(3)},1000)
    })
  }
).then(
  value= > {
    console.log('Results of Task 3', value)
  }
)
// Perform task 1(asynchronous)
// Result 1 of task 1
// Perform task 2(synchronization)
// Result 2 of Task 2
// Perform task 3(asynchronous)
// Result 3 of task 3
Copy the code

6.Promise abnormal penetration?

(1) When using promise’s then chain call, you can specify the failed callback at the end

(2) Any previous operation is abnormal, will be passed to the last failed callback processing

new Promise((resolve, reject) = > {
   //resolve(1)
   reject(1)
}).then(
  value= > {
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value= > {
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value= > {
    console.log('onResolved3()', value)
  }
).catch(
  reason= > {
    console.log('onRejected1()', reason)
  }
)
// onRejected1() 1
Copy the code

Throw reason => {throw reason}

new Promise((resolve, reject) = > {
   //resolve(1)
   reject(1)
}).then(
  value= > {
    console.log('onResolved1()', value)
    return 2
  },
  reason= > {throw reason} // Throw the result of failure reason
).then(
  value= > {
    console.log('onResolved2()', value)
    return 3
  },
  reason= > {throw reason} // Throw the result of failure reason
).then(
  value= > {
    console.log('onResolved3()', value)
  },
  reason= > {throw reason} // Throw the result of failure reason
).catch(
  reason= > {
    console.log('onRejected1()', reason)
  }
)
// onRejected1() 1
Copy the code

So the result of a failure is processed layer by layer and passed to the catch.

Alternatively, replace reason => {throw reason} with reason => promise.reject (reason)

7. Break the Promise chain?

When using a promise’s then chain call, it breaks in the middle, and no subsequent callback function is called

Solution: Return a Promise object in a pending state in the callback function

new Promise((resolve, reject) = > {
   //resolve(1)
   reject(1)
}).then(
  value= > {
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value= > {
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value= > {
    console.log('onResolved3()', value)
  }
).catch(
  reason= > {
    console.log('onRejected1()', reason)
  }
).then(
  value= > {
    console.log('onResolved4()', value)
  },
  reason= > {
    console.log('onRejected2()', reason)
  }
)
// onRejected1() 1
// onResolved4() undefined
Copy the code

To interrupt execution in a catch, write:

new Promise((resolve, reject) = > {
   //resolve(1)
   reject(1)
}).then(
  value= > {
    console.log('onResolved1()', value)
    return 2
  }
).then(
  value= > {
    console.log('onResolved2()', value)
    return 3
  }
).then(
  value= > {
    console.log('onResolved3()', value)
  }
).catch(
  reason= > {
    console.log('onRejected1()', reason)
    return new Promise(() = > {}) // Return a pending Promise
  }
).then(
  value= > {
    console.log('onResolved4()', value)
  },
  reason= > {
    console.log('onRejected2()', reason)
  }
)
// onRejected1() 1
Copy the code

Return a new promise in a catch that has no result.

Since the new promise result returned determines the result in the subsequent THEN, there is no result in the subsequent THEN either.

This achieves the effect of breaking the promise chain.

reference

Silicon Valley Web Front End Promise Tutorial from Getting Started to Mastering (Early Release 2021)

Silicon Valley Promise tutorial (Promise front-end advanced will learn)

Callback function -Promise

ECMAScript 6 Getting started with Promise objects