Demand:
A, read a| in turn b| C three files and terminates immediately if there is a failure.
B, simultaneous reading a| b| C three files and terminates immediately if there is a failure.
First, callback
需求A
:
Let read = function (code) {if (code) {return true; } else {return false; }}let Readfilea = function (callback) {if (read (1)) {return callback (NULL, "111"); } else {return callback ("a Fail"); }}let Readfileb = function (callback) {if (read (1)) {return callback (NULL, "222"); } else {return callback ("B fail"); }}let Readfilec = function (callback) {if (read (1)) {return callback (NULL, "333"); } else {return callback ("C Fail"); }}readfilea (err, data) {if (err) {console.log ("Open file" + err); Return } console.log ("Read A.txt succeeded! Content: "+ data"; Readfileb (err, data) {if (err) {console.log ("Open file" + err); Return } console.log ("Read B.txt succeeded! Content: "+ data"; Readfilec (err, data) {if (err) {console.log ("Open file" + err); Return } console.log ("Read C.txt succeeded! Content: "+ data"; }); });});
Return
读取 a.txt 成功!内容:111读取 b.txt 成功!内容:222读取 c.txt 成功!内容:333
需求B
: Too disgusting, not written, in short, very cumbersome.
Second, async.js
async.js
A detailed description of the library can be found in: [to be written]
需求A
:
async.series
var async = require("async");let read = function (code) { if (code) { return true; } else { return false; }}let readFileA = function (callback) { if (read(1)) { return callback(null, "111"); } else { return callback("a fail"); }}let readFileB = function (callback) { if (read(0)) { return callback(null, "222"); } else { return callback("b fail"); }}let readFileC = function (callback) { if (read(1)) { return callback(null, "333"); } else { return callback("c fail"); }}async.series([readFileA, readFileB, readFileC], function (err, datas) { if (err) { console.log("open file " + err); } console.log(datas); return; });
When a second Readfileb () read fails:
Return
open file b fail[ ‘111‘, undefined ]
需求B
:
async.parallel
var async = require("async");let read = function (code) { if (code) { return true; } else { return false; }}let readFileA = function (callback) { if (read(1)) { return callback(null, "111"); } else { return callback("a fail"); }}let readFileB = function (callback) { setTimeout(() => { if (read(0)) { return callback(null, "222"); } else { return callback("b fail"); } }, 1000);}let readFileC = function (callback) { if (read(1)) { return callback(null, "333"); } else { return callback("c fail"); }}async.parallel([readFileA, readFileB, readFileC], function (err, datas) { if (err) { console.log("open file " + err); } console.log(datas); return; });
When the second Readfileb () read fails (note that I added settimeout to it, in order to reflect the difference from the serial result above):
Return
open file b fail[ ‘111‘, undefined, ‘333‘ ]
Summary: Benefits of Async.js and callback:
1, the code is less, solve the callback Hell pyramid defect
2, async in the second parameter callback function, you can handle the error uniformly (it is recommended to use different error classes to distinguish)
3, the result of successful return datas can be summarized into an array for easy processing
Third, Promise
Expand
Promise Knowledge
new Promise()
// promise在new的时候已经开始运行 new Promise(() => console.log("I have already started!"));
Return
I have already started!
promise.then(successCallback, failureCallback);
new Promise((resolve, reject) => resolve()).then(function (data) { console.log("success");}, function (data) { console.log("fail");})
Return
success
promise.catch(failureCallback)
// promise.catch(failureCallback) 是 promise.then(null, failureCallback) 的缩略形式new Promise((resolve, reject) => reject()).catch( function (data) { console.log("fail");})
Return
fail
链式调用
// 链式调用的原理:then函数会返回一个新的promisenew Promise((resolve, reject) => reject()).then(function (data) { console.log("success_1");}, function (err) { console.log("fail_1");}).then(function (data) { console.log("success_2");}, function (err) { console.log("fail_2");});
Return
fail_1success_2
Questions
Q 1: then函数
A new promise will be returned, but then the Successcallback and Failurecallback are not able to invoke resolve () and reject () in the two callback functions, So how does this new promise specify the final state?
Then
in Successcallback and Failurecallback. |
equivalent to |
Do not return |
Resolve (undefined) |
Return 1 |
Resolve (1) |
Return Promise.resolve () |
Resolve () |
Return Promise.reject () |
Reject () |
Throw Error () |
Reject () |
return new Promise () |
And so on |
Instead of the normal promise object, if the call Resolve/reject is not displayed, nothing happens, for example:
new Promise((resolve, reject) => {return 1;}).then(function (data) { console.log("success");}, function (err) { console.log("fail");});
Return
Without any output
Q 2:then function if successCallback
and failureCallback
both are null, what happens?
Nothing will happen, .then(null, null)
as long as one of the parties is null equals to the next then to take over the callback
new Promise((resolve, reject) => reject()) .then(null, null) .then(null, null) .then(null, null) .then(null, null) .then(function (data) { console.log("success_2"); }, function (err) { console.log("fail_2"); });
So according to the above 2 questions revealed by the law , we can write the following elegant code :
// 链式调用的原理:then函数会返回一个新的promisenew Promise((resolve, reject) => resolve()).then((data) => { console.log("success_1");}).then((data) => { console.log("success_2"); throw Error("error");}).then((data) => { console.log("success_3");}).catch((err) => {
Return
success_1success_2Error: error ……
Note: .catch()
you can also continue to connect .then()
or.catch()
This achieves the following clear expression of the synchronization code of the other people's home:
try { let result = syncDoSomething(); let newResult = syncDoSomethingElse(result); let finalResult = syncDoThirdThing(newResult); console.log(`Got the final result: ${finalResult}`); } catch(error) { console.log(error);}
So, 需求A
:
Let read = function (code) {if (code) {return true; } else {return false; }}let Readfilea = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolv E ("111"); } else {reject ("a fail"); } });} Let Readfileb = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolve ( "222"); } else {reject ("B fail"); } });} Let Readfilec = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolve ( "333"); } else {reject ("C fail"); } });} [Serial] Scenario: preload multiple resources sequentially, or enter. catch () Readfilea () if there is a failure in the middle. Then (data) {Console.log ("read A.txt succeeded! Content: "+ data"; return Readfileb ();}). Then (the function (data) {Console.log ("read B.txt succeeded! Content: "+ data"; return Readfilec ();}). Then (the function (data) {Console.log ("read C.txt succeeded! Content: "+ data"; Return "read End";}). Then (function (data) {Console.log (data); return;}). catch (function (err) {console.log ("Open file" + err);})
Expand
promise
Vs事件监听
1\ events that occur multiple times on the same object (such as KeyUp, Touchstart, and so on)
The callback functions that were added through the. Then form, even those that were added after the asynchronous operation was completed, will be called, as shown above.
2\ If the promise has succeeded or failed, and you subsequently added a success/failure callback, the correct callback will be invoked, even if the event occurred earlier.
3\ is less concerned about the exact timing of certain features, and more about responding to results.
4\ even functions that are added after the asynchronous operation has been completed are called
Promise Extended Knowledge
Promise.resolve()
And
Promise.reject()
A quick way to manually create a promise that is already resolve or reject.
promise.all
: It also realizes
需求B
:
//promise.all [并行] 场景:预加载多个资源,都完成后才能进入页面Promise.all([readFileA(), readFileB(), readFileC()]).then(function (datas) { console.log(datas); //所有promise都resolve,返回array return;}).catch(function (err) { console.log("open file " + err); //只要有一个promise是reject,返回这个reject的value})
promise.race
:
//promise.race [并行] 场景:taskA:fetch图片,taskB:settimeout抛错,让两个task赛跑实现请求超时报错功能Promise.race([taskA(), taskB()]).then(function (data) { //进到resolve还是reject回调只取决于第一个确定状态的Promise console.log(data); return;}).catch(function (err) { console.log("读取图片超时");})
Summary: Benefits of Promise and callback:
1, the code is less, solve the callback Hell pyramid defect
2. Catch can handle errors uniformly (it is recommended to distinguish between different error classes)
Iv. async/await
需求A
:
Let read = function (code) {if (code) {return true; } else {return false; }}let Readfilea = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolv E ("111"); } else {reject ("a fail"); } });} Let Readfileb = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolve ( "222"); } else {reject ("B fail"); } });} Let Readfilec = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolve ( "333"); } else {reject ("C fail"); } });} Async function Test () {try {Let re_a = await Readfilea (); Let Re_b = await readfileb (); Let Re_c = await Readfilec (); Console.log ({re_a, Re_b, re_c}); If all succeeds, return: {re_a: ' 111 ', Re_b: ' 222 ', Re_c: ' 333 '}} catch (Err) {Console.log (err);//if B fails, return:b f Ail}}test ();
Summary: Benefits of Async/await and callback:
1, the least amount of code, to solve the problem of callback Hell Pyramid (Promise through then chain to solve the callback multi-layered callback pyramid, and now use async/await to further optimize it) (Promise-based async/ Await also tried to eliminate promise)
2. Catch can handle errors uniformly (it is recommended to distinguish between different error classes)
Expand
1, the Async function is the Generator function of the syntax of sugar, is not essentially synchronous code
2. Async is used to declare that a function is asynchronous, while an await (async wait) is used to wait for an asynchronous method to execute.
3,await can only appear in the Async function, so at the top of the code, we cannot use await, so add it. Then/catch to handle the final result or drop error is normal practice.
try { let re_a = await readFileA(); let re_b = await readFileB(); let re_c = await readFileC(); console.log({re_a, re_b, re_c}); } catch (err) { console.log(err); }
Return
Error
Or the top level using an immediate execution function expression (iife)
(async () => { try { let re_a = await readFileA(); let re_b = await readFileB(); let re_c = await readFileC(); console.log({re_a, re_b, re_c}); } catch (err) { console.log(err); } })()
Return
{ re_a: ‘111‘, re_b: ‘222‘, re_c: ‘333‘ }
Return
TypeError: (intermediate value)(...) is not a function
The above example can also be written like this:
async function test() { try { let re_a = await readFileA(); let re_b = await readFileB(); let re_c = await readFileC(); console.log({re_a, re_b, re_c}); //如果都成功,return: { re_a: ‘111‘, re_b: ‘222‘, re_c: ‘333‘ } } catch (err) { console.log(err); // 如果b失败,return: b fail }}test().then(function(data){ console.log("success");},function(err){
Return
{ re_a: ‘111‘, re_b: ‘222‘, re_c: ‘333‘ }success
4. In fact, the function returned by the async declaration is a Promise object , which is why await must be used in the async function. Async function calls do not cause blocking, and all of its internal blocking is encapsulated in an Promise object that executes asynchronously.
The difference is that theAsync declaration function can be achieved by the return value/throw exception to achieve the common Promise resolve ()/reject ()
The following is a peer relationship:
// async函数async function foo () { return ‘a‘}// Promisefunction foo () { return Promise.resolve(‘a‘)}
// async函数async function foo () { throw new Error(‘error‘)}// Promisefunction foo () { return Promise.reject(new Error(‘error‘))}
Use
promise.all
Realize
需求B
Async/await also applies Promise.all
, because the Promise.all itself returns the Promise object.
Let read = function (code) {if (code) {return true; } else {return false; }}let Readfilea = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolv E ("111"); } else {reject ("a fail"); } });} Let Readfileb = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolve ( "222"); } else {reject ("B fail"); } });} Let Readfilec = function () {return new Promise (function (resolve, reject) {if (read (1)) {Resolve ( "333"); } else {reject ("C fail"); } });} Async function Test () {try {Let re_a = await Readfilea (); Let Re_b = await readfileb (); Let Re_c = await Readfilec (); Console.log ({re_a, Re_b, re_c}); } catch (Err) {Console.log (err); }}async function Test () {try {Let results = await promise.all ([ReadfiLeA (), Readfileb (), Readfilec (),]); Console.log (results); } catch (Err) {Console.log (err); }}test ();
# # # Reference
[Using promises]
Https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises
[Understanding JavaScript's async/await]
1190000007535316
[Javascript.info-async/await]
Https://javascript.info/async-await#async-functions
Callback vs Async.js vs Promise vs Async/await