preface

To explore the role of promises, consider the following code: > Why are promises designed to be synchronous and. Then asynchronous?

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

});

// 异步
p.then((res) => {

})
Copy the code

To explore the

The following demo uses Ajax and Vite to build the test environment, with custom JSON data in data.json used to simulate a request to return network data

demo1

console.log('Promise Demo'); $.ajax({ url: 'http://localhost:3000/data.json', success (data) { console.log(handeData(data)); }}) // This sentence will not block console.log(' I am a developer'); function handeData(data) { return data.map(function(item) { return item.name; })}Copy the code

Consider the print order in the above program —–> result

Promise Demo I am a developer [" 三", "三"," 三"]Copy the code
  • Due to theajaxThe request is asynchronous, soconsole.log('i am a developer');Won’t be blocked

demo2

console.log('Promise Demo'); var data = $.ajax({ url: 'http://localhost:3000/data.json', async: false / / synchronization}) console. The log (handeData (data. ResponseJSON)); // This will block console.log(' I am a developer');Copy the code

Consider the print order in the above program —–> result

Promise Demo
["张三", "李四", "王五"]
i am a developer
Copy the code
  • Due to theajaxThe request has mandatory synchronization parameters setasync:falseSo the backconsole.log('i am a developer');It would be blocked, onlyajaxAfter the request returns data, execution can continue

demo3

// const p = new Promise((resolve,reject) => {$.ajax({url: 'http://localhost:3000/data.json', success (data) { resolve(data); }})}); // async p.teng ((res) => {console.log(handeData(res)); }) console.log('i am a developer');Copy the code

Consider the print order in the above program —–> result

Promise Demo I am a developer [" 三", "三"," 三"]Copy the code
  • Due to thePromiseIs synchronous, so it is executed immediately and returns an instancep
  • butPromiseDoes not block outp.thenOutside of the following procedures, so will be executed immediatelyconsole.log('i am a developer');
  • And becausePromiseIt’s a time-consuming operation, soconsole.log('i am a developer');Will be printed first

demo4

function getData() { return new Promise((resolve, reject) => { $.ajax({ url: 'http://localhost:3000/data.json', success (data) { resolve(data); } }) }) } async function doSomething() { const data = await getData(); console.log(handeData(data)); } doSomething() console.log('i am a developer'); function handeData(data) { return data.map(function(item) { return item.name; })}Copy the code

Consider the print order in the above program —–> result

Promise Demo I am a developer [" 三", "三"," 三"]Copy the code
  • Demo4 is actually a modified version of Demo3
  • willPromiseEncapsulate into onegetData()Function, usingawaitKeyword to modify this function method so that its outerdoSomething()A function is an asynchronous function; suchdoSomething()This function no longer blocks subsequent programsconsole.log('i am a developer'); The implementation of the

Demo5 is about hell nesting

console.log('Promise Demo'); function doSomethingWithoutPromise() { $.ajax({ url: 'http://localhost:3000/data0.json', success (data0) { console.log(data0); / / the following data1. Json. Please request based on data0 json data returned back data0 $. Ajax ({url: 'http://localhost:3000/data1.json' data: data0, success (data1) { console.log(data1); / / data2 below. Json based on data1. Please request json data returned back data1 $. Ajax ({url: 'http://localhost:3000/data2.json' data: data1, success (data2) { console.log(data2); } }) } }) } }) } doSomethingWithoutPromise(); console.log('i am a developer');Copy the code

Print the result

Promise Demo
i am a developer
{data0: "data0"}
{data1: "data1"}
{data2: "data2"}
Copy the code
  • You can seedoSomethingWithoutPromise();Internally it is asynchronous, so there is no blockingconsole.log('i am a developer');.
  • But in thedoSomethingWithoutPromise();Method because each of the three Ajax requests is based on the result returned by the previous request as a parameter, the next request can proceed.
  • This nesting of three Ajax requests makes it very intuitive for beginners to know the relationship between each request (which is actually an advantage).
  • Once more nested (such as internal andajaxRequest), becomes less intuitive, and code maintenance becomes cumbersome. And if complex data processing is added between each request, the intuitive reading will be much worse and error prone.

Demo6 uses Promise to optimize hell nesting

console.log('Promise Demo'); function getData0() { return new Promise((resolve, reject) => { $.ajax({ url: 'http://localhost:3000/data0.json', success (data) { console.log(data); resolve(data); } }) }) } function getData1(pram) { return new Promise((resolve, reject) => { $.ajax({ url: 'http://localhost:3000/data1.json', data: pram, success (data) { console.log(data); resolve(data); } }) }) } function getData2(pram) { return new Promise((resolve, reject) => { $.ajax({ url: 'http://localhost:3000/data2.json', data: pram, success (data) { console.log(data); resolve(data); ; } }) }) } async function doSomethingWithPromise() { const data0result = await getData0(); // You can do some complicated operations on data0Result here //... const data1result = await getData1(data0result); Data1result = data1result = data1result = data1result const data2result = await getData2(data1result); } doSomethingWithPromise() console.log('i am a developer');Copy the code

Print the result

Promise Demo
i am a developer
{data0: "data0"}
{data1: "data1"}
{data2: "data2"}
Copy the code
  • As with Dome5, the print order remains the same
  • butdoSomethingWithPromise()The structure of the function is divided into threePromiseIn the encapsulated functions, the structure is clearer
  • eachPromiseOf the wrapped functions (GetData0 (), getData1(), getData2()) independent of each other, maintainability is greatly increased
  • If there isGetData3 (), getData4 ()...Such functions need to be nested and can be easily added and maintained

conclusion

  • Demo1: Asynchronous time-consuming operations should not block the main thread
  • Demo2: A forcible time-consuming operation becomes a synchronization operation and blocks the subsequent execution of the entire program
  • Demo3 description:PromiseIs synchronous, but it returns an instance immediately and does not block the following program (not included).then)
  • Demo4: Encapsulate the Promise as a time-consuming function (time-consuming operation) to be used when invokedawaitKeyword to modify this time-consuming function, can become a synchronous operation; And the outer function plusasyncAfter the keyword is formedExternal asynchronous, internal synchronous
  • Problems with hell nesting: 1. Code is not intuitive 2
  • Use demo4 to optimize the problems caused by hell nesting

Back to the question posed at the beginning of the article: WhyPromiseIs designed to be synchronous, and.thenIs asynchronous?

Answer: Do not block any programs that have nothing to do with Promise

  • PromiseThe synchronization and.thenAsynchronous ability, achievedAsynchronous problem synchronizationSolutions.
  • Promise+.thenIn fact, it is to prevent subsequent programs blocked problems
  • Optimized hell nesting is also usedAsynchronous problem synchronizationThe ability to