Asynchronous processing method callback function, Promise, async

In the development process, we often encounter some asynchronous operations, such as ajax request, node read and write file, timing task and so on. In general, it is necessary to capture the data returned asynchronously so as to carry out the next operation. Here are several methods to deal with asynchronous execution

CallBack callback event

Callback, event callback, asynchronous processing is completed, and the asynchronous processing requirements can be achieved through the event call. There are classic ajax requests, node file operations, and so on. Here's a node non blocking code example:

var fs = require("fs");
var path = require("path");
fs.readFile(path.join(__dirname, '../public/user.json'), (err, data) => {
    if(err) throw err;
    let list = JSON.parse(data);
	console.log(list);
})

Here, the second parameter of the readFile function is the callback function completed by asynchronous processing

Promise

Promise is an asynchronous processing method often used in development. Here are the common methods of promise:

  • Basically, setTimeout is used as an example to define a promise object, generate a random number within 10 in one minute, and judge the size of the random number to simulate the success of asynchronous operation. If it is greater than 5, it is successful. Get the random value in then. The same is true for the failure
let promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        let random = Math.random() * 10;
        if(random > 5)
            resolve(random);
        else 
            reject(random);
    }, 1000)
})
promise
	.then(res => {
	    console.log(res, 'res')
	})
	.catch(err => {
	    console.log(err, 'rej')
	})
  • Promise.all: sometimes in the development process, it is necessary to process the data returned by several interfaces at the same time, which requires capturing the end state of several interfaces. Promise.all solves this problem. This method takes an array as a parameter, and each item in the array is a promise object. Specifically, create two promise objects, one returns' promise 1 'in 1s, and one returns' promise 2' in 2s. After using all, an array will be returned in 2s: ['promise 1', 'promise 2']
let promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('promise1')
    }, 1000);
});
let promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('promise2');
    }, 2000);
})
Promise.all([promise1, promise2])
    .then(res => {
        console.log(res, 'res'); // Print after 2s ['promise1 ','promise2']
    })
    .catch(err => {
        console.log(err, 'rej');
    })

If a promise fails, the error information of the promise object is captured in the catch, as follows:

let promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('promise1')
    }, 1000);
});
let promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('promise2');
    }, 2000);
})
Promise.all([promise1, promise2])
    .then(res => {
        console.log(res, 'res'); 
    })
    .catch(err => {
        console.log(err, 'rej'); // Print out 'promise2' after 2s
    })
  • promise.race, race, regardless of success or failure, returns the promise object completed first, and the following code returns the object completed in the fastest 1s
let promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('promise1')
    }, 1000)
})
let promise2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('promise2')
    }, 2000)
})
Promise.race([promise1, promise2])
    .then(res => {
        console.log(res, 'res') // Print out 'promise1' completed in the fastest 1s
    })
    .catch(err => {
        console.log(err, 'rej') //The same goes for mistakes
    })

async awite

promsie solves the problem of asynchrony, but there is a problem: chain callback. This makes the code hard to read, and async's writing rules solve this problem.

  • The async function returns a promise object
getResult: async function (vm) {
  return 'hello word'
}
getResult.then(res => {
	console.log(res); // hello word
})
  • Awite must be used in the function marked async. When the awite flag is executed, and a promise follows awite, it will wait for the promise object to finish executing before proceeding. If successful, the data of r1 will be returned and captured by the callback function then. When promise fails, it will jump out and be caught by the function catch
function getResult() {
  return new Promise((resolve, reject) => {
        setTimeout(() => {
            let r1 = Math.ceil(Math.random() * 10);
            console.log(r1);
            resolve(r1);
        }, 1000)
    })
}
(async function(){
    let r1 = await getResult();
    console.log('wait for r1 Execute after completion'); //It will be executed in 1s. If getResult fails, it will not be executed here
    return r1;
})()
 .then(res => {
     console.log(res); // After getResult is executed successfully, the randomly generated r1 will be returned
 })
 .catch(err => {
     console.log(err); // After getResult fails to execute, it will be caught by catch, including error information
 })
  • Solve the problem of promise chained callback: in the development process, when one interface calls the data that needs to be returned by another interface, you need to continue to call the interface in promsie.then. When there are many such relationships, the following situation will occur. Randomly generate three numbers, find the sum of the three numbers, and the final chain callback looks very messy and difficult to manage. (of course, promise.all can be used here, but once the request parameters in the interface need to rely on the results returned by the previous interface, the chain callback is still needed.)
function getR1() {
   return new Promise((resolve, reject) => {
       setTimeout(() => {
           let r1 = Math.ceil(Math.random() * 10);
           resolve(r1);
       }, 1000);
   });
}
function getR2(r1) {
   return new Promise((resolve, reject) => {
       setTimeout(() => {
           let r2 = Math.ceil(Math.random() * 10);
           resolve(r2);
       }, 1000);
   });
}
function getR3(r1, r2) {
   return new Promise((resolve, reject) => {
       setTimeout(() => {
           let r3 = Math.ceil(Math.random() * 10);
           resolve(r1 + r2 + r3);
       }, 1000);
   });
}
getR1()
   .then(r1 => {
   	   console.log(r1); // Print the value of a random number after 1s
       getR2(r1)
           .then(r2 => {
           	   console.log(r1 + r2); // Print the sum of two random numbers after 2s
               getR3(r1, r2)
                   .then(r3 => {
                       console.log(r1 + r2 + r3); // Print the sum of three random numbers after 3s
                   })
           })
   })

async is a perfect solution. Does the following code look much clearer

(async function(){
    let r1 = await getR1();
    let r2 = await getR2();
    let r3 = await getR3();
    console.log('Wait 3 s After implementation:', r1 + r2 + r3);
})()

promise object execution failure capture

(async function(){
	 let r1 = await getR1().catch(err => {
	     console.log(err);
	 });
})()
14 original articles published, 10 praised, 973 visited
Private letter follow

Tags: JSON

Posted on Wed, 11 Mar 2020 05:19:08 -0400 by Donny Bahama