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 both Successcallback and Failurecallback cannot invoke resolve () and reject (), and the new promise how to specify the most What about 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);})
promise
Vs事件监听
A. 事件监听
more of what happens on the same object more than once (e.g. KeyUp, touchstart, etc.)
And promise
more of the performance of the object eventually to what state, and can not be changed.
But there is a magic type that is consistent, 事件监听
and the promise
callback function that can bind multiple times to the response of the same event , as shown in the following example:
let promise = new Promise((resolve, reject) => { console.log("I have already started!"); resolve();})setTimeout(() => { promise.then(function (data) { console.log("success_1"); throw new Error(); }, function (err) { console.log("fail_1"); }); }, 2000);setTimeout(() => { promise.then(function (data) { console.log("success_2"); }, function (err) { console.log("fail_2"); }); }, 4000);
Return
I have already started!//又等待了2秒success_1(node:13150) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error(node:13150) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.//又等待了2秒success_2
B. Unlike 事件监听
if the promise has succeeded or failed, and a callback function has been added over time, the callback can still be invoked successfully. The above example can also be reflected.
C. 事件监听
more attention to the precise timing of certain functions promise
is more about responding to results.
Promise Extension API
Promise.resolve()
And
Promise.reject()
A quick way to manually create a promise that is already resolve or reject.
promise.all
: You can implement
需求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, 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' }
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, see the above example, in fact, the Async declaration function returns a Promise object , which is the reason that 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]
Developer.mozilla.org/zh-cn/docs/web/javascript/guide/using_promises
[Understanding JavaScript's async/await]
1190000007535316
[Javascript.info-async/await]