asynchronous-flow-control

StuQ分享专题《深入浅出js(Node.js)异步流程控制》完整版

MIT License

Stars
196
Committers
4

asynchronous-flow-control

StuQjsNode.js

jspromisegeneratorasyncNode.js

  • ava
  • coyieldable 5aysnc

i5ting CTOStuQ Moajs Node.js Node 4 Web Koa

  • ava

  • co

    • generator/yield
    • co
    • convert or compose
  • yieldable 5

  • async/await

  • callback vs hell

  • Node.jserror-firstEventEmitter

  • thunk

  • promise/a+

  • generator/yield

  • async/await

  • xxx-fy

ava

AVA

avamocha

  • es6aysnc/await
  • io

JavaScript Node.js IO AVA IO Pageres Mocha AVA 31 11

tjmochaava

  • callback
  • promise
  • generator
  • async function
test('synchronization', t => {})
test.cb('callback', t => {})
test('promise', t => {})
test('generator function',  function * (t) {})
test('async function', async t => {})
  • testtest.cbcallback
  • test3GeneratorAsync

$ npm init
$ npm i -D ava
$ npm i -D co-exec

jsajaxsetTimeout

1.js

import test from 'ava';

test('synchronization', t => {
  const a = /foo/;
  const b = 'bar';
  const c = 'baz';
  t.false(a.test(b) || b === c);
});


ajaxNode.jsapi

Node.js

  • error-first callback
  • EventEmitter

callbackapiEventEmitterEventEmitter

2.js

import test from 'ava';
const exec = require('child_process').exec

test.cb('error-first callback with setTimeout', t => {
    setTimeout(() => {
      t.pass();
      t.end();
    }, 2000);
});

test.cb('error-first callback with exec', t => {
  exec('cat *.js bad_file | wc -l',
    function (error, stdout, stderr) {
      t.pass();
      t.end();
  });
});

promise

Promise

PromiseCommon JSPromose/A+

jQueryPromisedefferedpromiseAngularjs$qpromiseq

3.js

import test from 'ava';

// promise
test('promise', t => {
  return Promise.resolve(3).then(n => {
      t.is(n, 3);
  });
});

generator

generatores6generatoryieldyieldyieldgenerator

avagenerator

4.js

import test from 'ava';

var exec = require('co-exec');

test('generatorFn with exec()', function * (t) {
    let commit = yield exec('ls -alt|grep .gitignore|wc -l');
    t.true(commit == 1);
});

async function

generatornextasync

asynces7 stage-3es7asyncawaityieldawaitpromise

5.js

import test from 'ava';

test('async function', async t => {
    const bar = Promise.resolve('bar');

    t.is(await bar, 'bar');
});

  asynchronous-flow-control git:(master)  ava -v *.js

   1  synchronization
   2  error-first callback with exec
   3  promise
   4  generatorFn with exec()
   5  async function
   2  error-first callback with setTimeout (2s)

  6 tests passed [09:48:27]

  asynchronous-flow-control git:(master)  ava -v *.js -s

   1  synchronization
   2  error-first callback with setTimeout (2s)
   2  error-first callback with exec
   3  promise
   4  generatorFn with exec()
   5  async function

  6 tests passed [09:48:35]
  • -s

6

js6:

  1. JavaScript: callback hell
  2. Thunk
  3. Promise/a+
  4. Generators/yield
  5. Async/AwaitES7 stage-3

*js

Promise

jsPromisecallback

nodePromise

promisecommonjspromise/Apromise/A+es6

The Promise object is used for asynchronous computations. A Promise represents an operation that hasn't completed yet, but is expected in the future.

PromisePromise

Node.js 0.129/116.27100%10/11Node.jsPromise0.12

Promise async/await API

node.jspromisebluebirdbenchmark

Promise

A promise is an abstraction for asynchronous programming. Its an object that proxies for the return value or the exception thrown by a function that has to do some asynchronous processing. Kris Kowal on JSJ

PromisePromisethenPromisePromisereject

  • promise
  • promise
var promise = new Promise(function(resolve, reject) {
  // do a thing, possibly async, then

  if (/* everything turned out fine */) {
    resolve("Stuff worked!");
  }
  else {
    reject(Error("It broke"));
  }
});

  • Promises Promise
  • promise promise Promise
  • ES6 Promises ECMAScript 6th Edition ES6prefix
  • Promises/A+ Promises/A+ ES6 Promises ES6 Promises
  • Thenable Promise .then

hello promise

apierror-firstapi

async/promise/hello.js

// callbacks
var fs = require("fs");

fs.readFile('./package.json', (err, data) => {
  if (err) throw err;
  console.log(data.toString());
});

promise

async/promise/hellopromise.js

// callbacks to promise
var fs = require("fs");

function hello (file) {
  return new Promise(function(resolve, reject){
    fs.readFile(file, (err, data) => {
    	if (err) {
    		reject(err);
    	} else {
    		resolve(data.toString())
    	}
    });
  });
}

hello('./package.json').then(function(data){
  console.log('promise result = ' + data)
}).catch(function(err) {
  console.log(err)
})

Node.jsapipromisefs.readFile

promise

new Promise(function(resolve, reject){
  
})
  • resolve
  • reject
hello('./package.json').then(function(data){

})
hello('./package.json').then(function(data){

}).catch(function(err) {

})

Promisecallbackthen

api

fs.readFile

fs.readFile('./package.json', (err, data) => {
  if (err) throw err;
  console.log(data.toString());
});

callback

function hello (file) {
  ...
}

Promise

function hello (file) {
  return new Promise(function(resolve, reject){
    ...
  });
}

resolvereject

function hello (file) {
  return new Promise(function(resolve, reject){
    fs.readFile(file, (err, data) => {
    	if (err) {
    		reject(err);
    	} else {
    		resolve(data.toString())
    	}
    });
  });
}

Node.jserror-firstcallbackNode.jsAPIPromise

Promise

Promise

PromisethenPromisePromise

// callbacks to promise
var fs = require("fs");

function hello (file) {
  return new Promise(function(resolve, reject){
    fs.readFile(file, (err, data) => {
    	if (err) {
    		reject(err);
    	} else {
    		resolve(data.toString())
    	}
    });
  });
}

function world (file) {
  return new Promise(function(resolve, reject){
    fs.readFile(file, (err, data) => {
    	if (err) {
    		reject(err);
    	} else {
    		resolve(data.toString())
    	}
    });
  });
}

function log(data){
  return new Promise(function(resolve, reject){
    console.log('promise result = ' + data)
    resolve(data)
  });
}

hello('./package.json').then(log).then(function(){
  return hello('./each.js').then(log)
}).catch(function(err) {
  console.log(err)
})

  • hello``world``log Promise
  • hello('./each.js').then(log)

Promise

thenable

promosethenthenPromise.prototypePromise

Promise.prototype.then = function(sucess, fail) {
    this.done(sucess);
    this.fail(fail);
    return this;
};

thisthen

then2

  • sucessfulfilled
  • failrejected

sucess

Promisepending, fulfilled rejected.

  • pending: , fulfilled rejected.
  • fulfilled: .
  • rejected: .

pendingfulfillpengdingrejectfulfilledreject

Promise

pending,promise

  • fulfilledrejected

fulfilled,promise

rejected,promise

identity

rejectresove

PromisePromisethen

Promise

new Promise(function(resolve, reject){
  
})

fsreflow.js

way 1

hello('./package.json').then(function(data){
  console.log('way 1:\n')
  return new Promise(function(resolve, reject){
    console.log('promise result = ' + data)
    resolve(data)
  });
}).then(function(data){
  return new Promise(function(resolve, reject){
    resolve('1')
  });
}).then(function(data){
  console.log(data)
  
  return new Promise(function(resolve, reject){
    reject(new Error('reject with custom err'))
  });
}).catch(function(err) {
  console.log(err)
})

thenpromiseresolverejectpromise

way 2

hello('./package.json').then(function(data){
  console.log('\n\nway 2:\n')
  return new Promise(function(resolve, reject){
    console.log('promise result = ' + data)
    resolve(data)
  }).then(function(data){
    return new Promise(function(resolve, reject){
      resolve('1')
    });
  }).catch(function(err) {
    console.log(err)
  })
}).then(function(data){
  console.log(data)
  
  return new Promise(function(resolve, reject){
    reject(new Error('reject with custom err'))
  });
}).catch(function(err) {
  console.log(err)
})

thenthen

way 3refact

var step1 = function(data){
  console.log('\n\nway 3:\n')
  return new Promise(function(resolve, reject){
    console.log('promise result = ' + data)
    resolve(data)
  }).then(function(data){
    return new Promise(function(resolve, reject){
      resolve('1')
    });
  }).catch(function(err) {
    console.log(err)
  })
}

var step2 = function(data){
  console.log(data)
  
  return new Promise(function(resolve, reject){
    reject(new Error('reject with custom err'))
  });
}

hello('./package.json').then(step1).then(step2).catch(function(err) {
  console.log(err)
})

Promise

way 4final

: require-directory

commonjsrequirerequirerequire-directory

commonjs

reflow/tasks/index.js

var requireDirectory = require('require-directory');
module.exports = requireDirectory(module);

reflow/taskscommonjs

reflow/tasks/hello.js

var fs = require("fs");

module.exports = function hello (file) {
  return new Promise(function(resolve, reject){
    fs.readFile(file, (err, data) => {
    	if (err) {
    		reject(err);
    	} else {
    		resolve(data.toString())
    	}
    });
  });
}

module.exports

step1step2

var tasks = require('./tasks')

tasks.hello('./package.json').then(tasks.step1).then(tasks.step2).catch(function(err) {
  console.log(err)
})

require('./tasks')tasksPromise

step1step2

var tasks = require('./tasks')

tasks.hello('./package.json').then(tasks.step2).then(tasks.step1).catch(function(err) {
  console.log(err)
})

catch

promise.then(function(result) {
  console.log('Got data!', result);
}).catch(function(error) {
  console.log('Error occurred!', error);
});

then

promise.then(function(result) {
  console.log('Got data!', result);
}).then(undefined, function(error) {
  console.log('Error occurred!', error);
});

thenreject

promisetry/catchtry/catchTODO:

try {
  throw new Error('never will know this happened')
} catch (e) {}

promises

readFile()
  .then(function (data) {
    throw new Error('never will know this happened')
  })

errors.then(null, onRejected)

readFile()
  .then(function (data) {
    throw new Error('now I know this happened')
  })
  .then(null, console.error)

errorQdoneerror

api/catch.js

var p1 = new Promise(function(resolve, reject) {
  resolve('Success');
});

p1.then(function(value) {
  console.log(value); // "Success!"
  return Promise.reject('oh, no!');
}).catch(function(e) {
  console.log(e); // "oh, no!"
  // return Promise.reject('oh, no! 2');
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});
$ node api/catch.js
Success
oh, no!
after a catch the chain is restored

api/catch2.js

var p1 = new Promise(function(resolve, reject) {
  resolve('Success');
});

p1.then(function(value) {
  console.log(value); // "Success!"
  return Promise.reject('oh, no!');
}).catch(function(e) {
  console.log(e); // "oh, no!"
  return Promise.reject('oh, no! 2');
}).then(function(){
  console.log('after a catch the chain is restored');
}, function () {
  console.log('Not fired due to the catch');
});
$ node api/catch2.js
Success
oh, no!
Not fired due to the catch

Node.jspromise

PromisePromise

package repo alias
bluebird petkaantonov/bluebird bb
es6-promise jakearchibald/es6-promise
es6-promise-polyfill [^1] lahmatiy/es6-promise-polyfill
es6-promises Octane/Promise
lie calvinmetcalf/lie
native-promise-only getify/native-promise-only npo
promiscuous RubenVerborgh/promiscuous
promise then/promise then
promiz Zolmeister/promiz
q kriskowal/q
rsvp tildeio/rsvp.js
vow dfilatov/vow
when cujojs/when w

[^1]: based on es6-promise, so excluded from the registery by default

Promise

Q Promises Deferreds 2009Node.jsIO API Q-IO

Promise promisepromise

Q Bluebird API referenceBluebirdBluebird

QQDeferredjQueryDeferred Coming from jQuery

BluebirdPromise Promise

bluebird

tj: bluebird is MASSIVE, why not use v8's?

bluebirdNode.jsapiPromise

bluebird

$ npm i -S bluebird

hellopromise-bb.js

// callbacks to promise
var fs = require("fs");
var Promise = require("bluebird");


function hello (file) {
  return new Promise(function(resolve, reject){
    fs.readFile(file, (err, data) => {
    	if (err) {
    		reject(err);
    	} else {
    		resolve(data.toString())
    	}
    });
  });
}

hello('./package.json').then(function(data){
  console.log('promise result = ' + data)
}).catch(function(err) {
  console.log(err)
})

hellopromise.js

var Promise = require("bluebird");

Node.jsPromisebluebird0

var``Promisekoaexpressweb

globalapp.js

global.Promise = require("bluebird");

Node.js native promise bluebird bluebird

  • nodePromisev8jsCCpromisejs
  • nodenew Promise3closures

http://programmers.stackexchange.com/questions/278778/why-are-native-es6-promises-slower-and-more-memory-intensive-than-bluebird

Promisification

Promisification means converting an existing promise-unaware API to a promise-returning API.

bluebirdpromisefypromisifyAll

promisifyAllpromisifypromisify

var Promise = require("bluebird");
var fs = Promise.promisifyAll(require("fs"));

fs.readFileAsync("./package.json", "utf8").then(function(contents) {
    console.log(contents);
}).catch(function(e) {
    console.error(e.stack);
});

abc 3bluebirdpromisifyAllpromise

var Promise = require("bluebird");

var obj  = { 
  a: function(){
    console.log('a')
  },
  
  b: function(){
    console.log('b')
  },
  
  c: function(){
    console.log('c')
  }
}

Promise.promisifyAll(obj);

obj.aAsync().then(obj.bAsync()).then(obj.cAsync()).catch(function(err){
  console.log(err)
})

promisifyAllerrorbluebird

Promise5api

1

new Promise( /* executor */ function(resolve, reject) { ... } );

Promise2resolvereject

  • resolvependingfulfilled
  • rejectpendingrejected
    • Promise.prototype.then()reject
    • Promise.prototype.catch()reject

resolvePromise.resolverejectPromise.reject

promise/api/a.js

new Promise(function(resolve){
    resolve(1);
}).then(function(value){
    console.log('new Promise ' + value);
});

Promise.resolve(1).then(function(value){
    console.log('Promise.resolve ' + value);
});

2resolvePromise.resolve

promise/api/b.js

var error = new Error('this is a error')

new Promise(function(resolve, reject){
    reject(error);
}).catch(function(err){
    console.log('new Promise ' + err);
});

Promise.reject(error).catch(function(err){
    console.log('Promise.resolve ' + err);
});

2rejectPromise.reject

resolverejectpromise/api/c.js

// 
new Promise(function(){
    return Promise.resolve(1)
}).then(function(value){
    console.log('Promise.resolve 1 ' + value);
});

Node.jsPromise

promise/api/d.js

// 
function hello(i){
    return Promise.resolve(i)
}

hello(1).then(function(value){
    console.log('Promise.resolve 1 ' + value);
});

Promise.resolvePromisenew Promise(resolve, reject)

PromisePromise

i

promise/api/e.js

// 
function hello(i){
  if (i % 2 == 0) {
    return Promise.resolve(i)
  } else {
    return Promise.reject(i)
  }
}

hello(1).then(function(value){
    console.log('Promise.reject 1 ' + value);
});

hello(2).then(function(value){
    console.log('Promise.resolve 1 ' + value);
});

Promise.resolvePromise.reject

Promise.resolve(value); Promise.resolve(promise); Promise.resolve(thenable);

Promise.reject(reason);

2Promise.prototype.then()

p.then(onFulfilled, onRejected);

p.then(function(value) { // fulfillment }, function(reason) { // rejection });

3Promise.prototype.catch()

p.catch(onRejected);

p.catch(function(reason) { // rejection });

4

  • Promise.all(iterable)
  • Promise.race(iterable)

Promise.all promise FulFilled Rejected Promise.race promise FulFilled Rejected

allthenraceoncethen

promise

all.js

'use strict'

let sleep = (time, info) => {
  return new Promise(function (resolve) {
    setTimeout(function () {
        console.log(info)
        resolve('this is ' + info)
    }, time)
  })
}

let loser = sleep(1000, 'loser')
let winner = sleep(4, 'winner')

// main
Promise.all([winner, loser]).then(value => {
    console.log("then: " + value)    // => 'this is winner'
})

$ node api/all.js 
winner
loser
then: this is winner,this is loser

race.js

'use strict'

let sleep = (time, info) => {
  return new Promise(function (resolve) {
    setTimeout(function () {
        console.log(info)
        resolve('this is ' + info)
    }, time)
  })
}

let loser = sleep(1000, 'loser')
let winner = sleep(4, 'winner')

// main
Promise.race([winner, loser]).then(value => {
    console.log("then: " + value)    // => 'this is winner'
})
$ node api/race.js
winner
then: this is winner
loser

  1. Promises/A
  2. Promises/B
  3. Promises/D
  4. Promisejs
  5. Promises/A+
  6. As soon as possible
  7. A minimalist implementation of a javascript promise
  8. Lightweight implementation of promises
  9. How is a promise/defer library implemented?
  10. Basic Javascript promise implementation attempt
  11. You're Missing the Point of Promises
  12. Boom! Promises/A+ Was Born
  13. Futures and promises
  14. JavaScript Promises - There and back again
  15. Promise
  16. https://blog.domenic.me/youre-missing-the-point-of-promises/
  17. https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/
  18. https://github.com/kriskowal/q/wiki/General-Promise-Resources
  19. https://www.w3.org/2001/tag/doc/promises-guide
  20. https://github.com/bevacqua/promisees

https://github.com/calvinmetcalf/lie/blob/master/lib/index.js

co

es6generatortjcocogeneratoryieldyieldable

cogenerator

:

  • ES6Generator
  • ES62for-of
  • coco2
  • yieldable 5Thunk
  • koaconvertcompose

generator/yield

generator

function* doSomething() {
    console.log('1');
    yield; // Line (A)
    console.log('2');
}

var gen1 = doSomething();

gen1.next(); // Prints 1 then pauses at line (A)
gen1.next(); // resumes execution at line (A), then prints 2
  • gen1generator
  • next1 yieldLine (A)
  • nextline (A)2

yieldnext

tjcogeneratorcov4Promise

co

co : The ultimate generator based flow-control goodness for nodejs (supports thunks, promises, etc)

var co = require('co');

co(function *(){
  // yield any promise
  var result = yield Promise.resolve(true);
})

coco2api

  • co(function *(){}) generator
  • co.wrap(function *(param){}) generator
var fn = co.wrap(function* (val) {
  return yield Promise.resolve(val);
});

fn(true).then(function (val) {

});

co

[email protected]

// 
function co(gen) {
  // this
  var ctx = this;
  var args = slice.call(arguments, 1)

  // we wrap everything in a promise to avoid promise chaining,
  // which leads to memory leak errors.
  // see https://github.com/tj/co/issues/180
  // coPromisethencatch
  return new Promise(function(resolve, reject) {
    // Promise
    onFulfilled();

    /**
     * @param {Mixed} res
     * @return {Promise}
     * @api private
     */

    function onFulfilled(res) {
      var ret;
      try {
        ret = gen.next(res);
      } catch (e) {
        return reject(e);
      }
      next(ret);
    }

    /**
     * @param {Error} err
     * @return {Promise}
     * @api private
     */
    // Promise
    function onRejected(err) {
      var ret;
      try {
        ret = gen.throw(err);
      } catch (e) {
        return reject(e);
      }
      next(ret);
    }

    // generator
    // ret.doneret.value
    // 
    function next(ret) {
      // resolvepromise
      if (ret.done) return resolve(ret.value);
      // yieldpromise
      //  promisegeneratorgeneratorFunctionarrayobject
      // toPromisepromise
      var value = toPromise.call(ctx, ret.value);
      // promiseonFulfilled, onRejectedpromisenext
      // generatornext
      // return value.then(onFulfilled, onRejected);onFulfilled
      // onFulfillednext(ret);
      if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
      
      // 
      return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
        + 'but the following object was passed: "' + String(ret.value) + '"'));
    }
  });
}
  • PromiseonFulfilledonRejected
  • generatornextnext{value:'',done: true}

onFulfillednext(ret)generatornext()

next(ret)onFulfilledonRejectednext(ret)

// generator
// ret.doneret.value
// 
function next(ret) {
  // resolvepromise
  if (ret.done) return resolve(ret.value);
  // yieldpromise
  //  promisegeneratorgeneratorFunctionarrayobject
  // toPromisepromise
  var value = toPromise.call(ctx, ret.value);
  
  // promiseonFulfilled, onRejectedpromisenext
  // generatornext
  // return value.then(onFulfilled, onRejected);onFulfilled
  // onFulfillednext(ret);
  if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
  
  // 
  return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
    + 'but the following object was passed: "' + String(ret.value) + '"'));
}

1:

  // resolvepromise
  if (ret.done) return resolve(ret.value);

2 nextonFulfilled

  // promiseonFulfilled, onRejectedpromisenext
  // generatornext
  // return value.then(onFulfilled, onRejected);onFulfilled
  // onFulfillednext(ret);
  if (value && isPromise(value)) return value.then(onFulfilled, onRejected);
  

3:

  // 
  return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, '
    + 'but the following object was passed: "' + String(ret.value) + '"'));

co2apigeneratorwrap

// generator
co.wrap = function (fn) {
  createPromise.__generatorFunction__ = fn;
  return createPromise;
  function createPromise() {
    // argumentsfn
    // callapplyjs api
    return co.call(this, fn.apply(this, arguments));
  }
};

callapply

cnode co 4.6

koaconvert or composeKoa

yieldable 5

yieldablegeneratoryieldyield6yieldyieldableyield

  • promises
  • thunks (functions)
  • array (parallel execution)
  • objects (parallel execution)
  • generators and generatorFunctions
    • promises
    • thunks
    • array
    • objects

PromisethunksPromisethenableco v4.6Promise

generatorgeneratorFunctionyieldyield*koa 1.x2.x

promises

thunks (functions)

"" Thunk

thunk?

  • thunk
  • thunk callback CPS
  • thunk thunk
  • thunk callback
  • callback thunk thunk thunk thunk

JavaScript Thunk

// readFile
fs.readFile(fileName, callback);

// ThunkreadFile
var readFileThunk = Thunk(fileName);
readFileThunk(callback);

var Thunk = function (fileName){
  return function (callback){
    return fs.readFile(fileName, callback); 
  };
};

fs readFile Thunk

Thunk Thunk

var Thunk = function(fn){
  return function (){
    var args = Array.prototype.slice.call(arguments);
    return function (callback){
      args.push(callback);
      return fn.apply(this, args);
    }
  };
};

fs.readFile Thunk

var readFileThunk = Thunk(fs.readFile);
readFileThunk(fileA)(callback);

array (parallel execution)

co(function* () {
  var res = yield [
    Promise.resolve(1),
    Promise.resolve(2),
    Promise.resolve(3),
  ];
  console.log(res); // => [1, 2, 3]
}).catch(onerror);

objects (parallel execution)

co(function* () {
  var res = yield {
    1: Promise.resolve(1),
    2: Promise.resolve(2),
  };
  console.log(res); // => { 1: 1, 2: 2 }
}).catch(onerror);

Generators and Generator Functions

Any generator or generator function you can pass into co can be yielded as well. This should generally be avoided as we should be moving towards spec-compliant Promises instead.

koa 1.x

app.use(function *(next){
  var start = new Date;
  yield next;
  var ms = new Date - start;
  console.log('%s %s - %s', this.method, this.url, ms);
});

koa 2.x

app.use(co.wrap(function *(ctx, next) {
  const start = new Date();
  yield next();
  const ms = new Date() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
}));

async/await

JavaScript

Promise Generator

I/Ogeneratoryieldable

generatorco

coYieldable

async/await

Async

ES7 stage-3 async/await es7Async coreadme.md

async Promise await Promise resolve

async function a1() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000);
  })
}

async function a2() {
  await a1();
  console.log("2333");
}
a2()

async / awaitF#C# 4.0MSDN

PromisePromisethen

await / asynctry..catchtry..catchJavaScriptPromisereject

await

  • await + async
  • await + Promise
  • await + cocoPromiseYieldable

2copromisehack

async function a2() {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, 1000);
  })
}

async function a1() {
  console.log("hello a1 and start a2");
  await a2();
  console.log("hello end a2");
}

async function a0() {
  console.log("hello a0 and start a1");
  await a1();
  console.log("hello end a1");
}

a0()

Promise

awaitPromise

var asyncFn = async function () {
  return new Promise(function (resolve, reject) {
    try {
      await somecall();
      resolve(somevalue);
    } catch (err) {
      reject(err);
    }
  });
};

console.log(await asyncFn());

yield2yieldarrayobjectAsyncawaitPromise

awaitPromisePromisePromise2apiallrace

async/array.js

'use strict'

let sleep = (time, info) => {
  return new Promise(function (resolve) {
    setTimeout(function () {
        console.log(info)
        resolve('this is ' + info)
    }, time)
  })
}

let loser = sleep(1000, 'loser')
let winner = sleep(4, 'winner')


async function main() {
  await Promise.all([winner, loser]).then(value => {
    console.log("then: " + value)    // => 'this is winner'
  })
  console.log("hello world");
}

main()
$ runkoa array.js
array.js
3babel presets path = /Users/sang/.nvm/versions/node/v4.4.5/lib/node_modules/runkoa/node_modules/
winner
loser
then: this is winner,this is loser
hello world
await Promise.all([])

raceall

Yieldable

awaitPromise coyield function, promise, generator, array, or objectyieldyieldableyield

  • function(as Thunks)
  • promise
  • array
  • object
  • generatorFunctionyield *

co Promise

  • awaitPromise
  • coPromise
await co(xxxx)

asyncPromiseco

async

Async

ChakraCore\Chromegenerator

ChakraawaityieldyieldawaittokenJs::OpCode::YieldChakraawaitParserByteCodeEmitter::Emit

case knopAwait:
case knopYield:
    byteCodeGenerator->StartStatement(pnode);
    funcInfo->AcquireLoc(pnode);
    Emit(pnode->sxUni.pnode1, byteCodeGenerator, funcInfo, false);
    EmitYield(pnode->sxUni.pnode1->location, pnode->location, byteCodeGenerator, funcInfo);
    funcInfo->ReleaseLoc(pnode->sxUni.pnode1);
    byteCodeGenerator->EndStatement(pnode);
    break;

awaityield

chromenodenodeV8v8ecma 262

Mikeal Rogersv8Async10

Node.js AsyncgeneratornativeAsyncKoa 2.xAsyncweb

Node.jstry/catcherror-firstasyncawaittry/catch

try {
  console.log(await asyncFn());
} catch (err) {
  console.error(err);
}

Promise

  • then(onFulfilled, onRejected)onRejected
  • catch

  • promisepromisefyAll
  • async

webdaopromiseserviceasync/await

daopromise

  • crud
  • promise

promisefyAll

servicemodelawait

  • async
  • asyncgenerator
  • asynctry/catchpromise
  • awaitPromisePromise
  • awaitPromisePromisethen

  • Promiseasyncgenerator
  • Generator
  • Async

****Promise

****Async + Promise

AVAKoa 2.x Node 4 Web Koa StuQKoastuqkoa