博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈异步调用几种方式
阅读量:6871 次
发布时间:2019-06-26

本文共 4470 字,大约阅读时间需要 14 分钟。

什么是异步/同步调用

异步调用就是你 喊 你朋友吃饭 ,你朋友说知道了 ,待会忙完去找你 ,你就去做别的了。
同步调用就是你 喊 你朋友吃饭 ,你朋友在忙 ,你就一直在那等,等你朋友忙完了 ,你们一起去。

异步不支持try/catch,try/catch只针对同步代码

  1. Callback
    callback就是在回调函数,在函数中会作为参数来实现:
let fs = require('fs'); // readFilefs.readFile('./2.promise/1.txt','utf8',function(err,data){ // error-first    fs.readFile(data,'utf8',function(err,data){ // error-first        console.log(data);    });});// 并行 无法在同一时刻合并两节异步的结果,异步方案不支持returnfs.readFile('./2.promise/1.txt','utf8',function(err,data){ // error-first});fs.readFile('./2.promise/2.txt','utf8',function(err,data){ // error-first    console.log(data);});复制代码

高阶函数

函数可以作为参数或者函数还可以作为返回值

1)批量生成函数

function isType(type){ // 偏函数    return function(content){        return Object.prototype.toString.call(content) === `[object ${type}]`;    }}let isString = isType('String');let isArray = isType('Array');console.log(isArray('hello'));复制代码

2)预置函数作为参数 loadsh _.after

function after(times,callback){    return function(){        if(--times === 0){            callback();        }    }}let eat = after(3,function(){    console.log('饱了')})eat();eat();eat();复制代码

2. Promise

callback虽然也能解决问题,但是要是多个函数嵌套的话不仅不好看难以维护,还会形成回调地狱。这个时候promise就出来啦!

let promise = new Promise(function (resolve,reject) {    resolve(100)})//链式调用的特点,将第一次成功的返回值当成下一次回调函数的参数let p2 = promise.then(function (data) {    return new Promise(function (resolve,reject) {        resolve(data)    })},function () {})p2.then().then().then(function (data) {    console.log(data);},function(err){    console.log(err)})复制代码

promise 解决了回调地狱的问题,还解决了同步异步的返回结果,按照顺序执行

3. generator + co(Promise)

是由tj 写的一个自动迭代的库。generator函数要用*来标识,yield(暂停,产出),它将函数分割成很多块,用next来往下执行,返回结果是一个迭代器,yield后面跟着的是value值,yield等号前面的是我们当前调用next传进来的,但是第一次传进来是无效的:

function* read() {    console.log(1);    let a = yield '珠峰';    console.log(a);    let b = yield 9    console.log(b);    return b;}let it = read();console.log(it.next('213')); // {value:'珠峰',done:false}console.log(it.next('100')); // {value:9,done:false}console.log(it.next('200')); // {value:200,done:true}console.log(it.next('200')); // {value:200,done:true}复制代码

看co的源码就会发现co()执行返回的是一个new Promise:

// 异步 generator主要和promise搭配使用let bluebird = require('bluebird');let fs = require('fs');let read = bluebird.promisify(fs.readFile);//promisify可以转化成promisefunction* r() {    let content1 = yield read('./2.promise/1.txt', 'utf8');    let content2 = yield read(content1, 'utf8');    return content2;}// co库 npm install co 可以自动的将generator进行迭代// let co = require('co');function co(it) {    return new Promise(function (resolve, reject) {        function next(d) {            let { value, done } = it.next(d);            if (!done) {                value.then(function (data) { // 2,txt                    next(data)                }, reject)            } else {                resolve(value);            }        }        next();    });}co(r()).then(function (data) {    console.log(data)})// generator原理是将一个函数划分成若干个小函数,没次调用时移动指针,内部是一个条件判断,走对应的逻辑// it.next().value.then(function(data){ // 2.txt//     it.next(data).value.then(function(data){//         console.log(it.next(data).value);//     });// })复制代码

这里有一个插件就是bluebird,它有个promisify的方法,是可以将参数promise化。另外他的promisifyAll方法是将一个方法下面的函数转化成promise。:

let fs = require('fs');let bluebird = require('bluebird');function promisify(fn) { // promise化 将回调函数在内部进行处理    return function (...args) {        return new Promise(function (resolve, reject) {            fn(...args, function (err, data) {                if (err) reject(err);                resolve(data);            })        })    }}function promisifyAll(obj) {    Object.keys(obj).forEach(key => { // es5将对象转化成数组的方法        if (typeof obj[key] === 'function') {            obj[key + 'Async'] = promisify(obj[key])        }    })}promisifyAll(fs); // 将所有的方法全部增加一个promise化fs.readFileAsync('./2.promise/1.txt', 'utf8').then(function (data) {    console.log(data);});复制代码

4.async await

号称异步调用的终极解决方案,成功解决了回调地狱,并发执行异步,在同一时刻同步返回结果,Promise.all,解决返回值问题,可以实现try,catch.

let bluebird = require('bluebird');let fs = require('fs');let read = bluebird.promisify(fs.readFile);// 用async 来修饰函数,aysnc需要配await,await只能promise// async和await(语法糖)  === co + generatorasync function r(){    try{        let content1 = await read('./2.promise/100.txt','utf8');        let content2 = await read(content1,'utf8');        return content2;    }catch(e){ // 如果出错会catch        console.log('err',e)    }}// async函数返回的是promise,r().then(function(data){    console.log('flag',data);},function(err){})复制代码

转载地址:http://iapfl.baihongyu.com/

你可能感兴趣的文章
PHP开发者常犯的10个MySQL错误
查看>>
物联网在交通领域示范应用的三大趋势
查看>>
浅谈如何用Java操作MongoDB?
查看>>
Java ConcurrentModificationException异常原因和解决方法
查看>>
2015 年对 GitLab 来说是非常棒的一年
查看>>
《编写高质量代码:改善c程序代码的125个建议》——建议17-1:先处理正常情况,再处理异常情况...
查看>>
《Docker技术入门与实战》——3.2 查看镜像信息
查看>>
Linux有问必答:如何在CentOS或RHEL 7上修改主机名
查看>>
JVM的持久代——何去何从?
查看>>
Kafka Producer接口
查看>>
《jQuery、jQuery UI及jQuery Mobile技巧与示例》——9.8 技巧:指定自定义的过渡动画...
查看>>
《NLTK基础教程——用NLTK和Python库构建机器学习应用》——第2章 文本的歧义及其清理...
查看>>
《Hack与HHVM权威指南》——1.3.3 属性
查看>>
MongoDB Schema Design
查看>>
基于Quick BI的用户分布分析
查看>>
对《架构即未来:现代企业可扩展的web架构、流程和组织》这本书的读后感。...
查看>>
微服务架构的分布式事务解决方案
查看>>
Spark修炼之道(高级篇)——Spark源码阅读:第五节 Stage提交
查看>>
iOS8到iOS9 变化笔记
查看>>
Linux之iconv转换文本格式的问题
查看>>