每天学习一点点,成功增加一大步

NodeJs笔记:实现异步执行改成同步执行的方案

NodsJS zhanghui 1258℃

众所周知,在 JavaScript 中的执行方法常是以异步方式来执行的,也就是无论当前的方法有没有执行完,JavaScript  都会在同级代码中继续往下执行,为了解决这个方法我们常常会以回调的方法来解决,但如果层次多了话自然的会进入“回调地狱”中。那么在 NodeJs 中也同样会遇到“埃及金字塔”事件。

在这里可使用 bluebird 来解决,起初我也没有一下子它的使用原理,网络上也有关于它的案例,但都没有说明它的语法究竟如何使用,于是呼我研究了半天功夫终于搞清楚了它的基本的使用。

首先使用 npm 在项目中安装

npm install bluebird --save

然后就可以在被使用同步执行的方法体中输入

private _functionName(parmas: any) {
    return new Promise((resolve, reject) => {
        // 在这里输入要执行方法体的代码
        // resolve 是指当执行成功时的返回
        // reject 是指当执行不成功时的返回
    });
}

最后在接收返回的处理

this._functionName(this.parmas).then((res) => {
    // res 就是 resolve 的返回
    callback(res);
}).catch((err) => {
    // err 就是 reject 的返回
    callback(err);
});

async / await

刚接触 node 原以为上面第三步的 then 处理是完成了同步的处理,后面发现还不是呢,它只是解决了回调的问题,要想实现真正的同步处理,还需要 async / await 的搭配,在上面的第二步之后用以下写法才能解决真正的同步问题。但要注意一点的是 await 要必须在 async 方法体内,不然 是会报错(之前一直掉进这个坑)。

async execute() {
    console.log('start');
    await this._functionName();
    console.log('end');
    return true;
}

Promise.map / linq

最后再写一点关于循环中异步变同步,大家都知道 javaScript 中无论是 for 循环,还是 forEach 循环,如果循环体内有方法(或者是函数)的话也会是一种异步处理,但有时候我们很想知道这循环中的过程什么时候执行完,按照 javaScript 原生的写法是无法达到想要的目的,很多时候循环完了,但里面真正要执行的过程还没有结束,要解决这个问题只能是异步变同步,或者是回调,但回调多了会掉进“回调地狱”。所以下面就使用 “promise.map”或“linq”的方法来解决,同样的假设以上第二步的方法为例。

promise.map 的例子:

/**
 * dataList 是被循环的数组
 */
return Promise.map(dataList, async (item, index) => {
    // console.log(index, item);
    return this._functionName(item).then(res => {
        
    });
});

2018-09-17 记 p-map 据说是可以解决 promise.map 的异步执行的问题

p-map:https://github.com/sindresorhus/p-map

linq 的例子:

import * as Enumerable from 'linq';

var result: string[] = [];
Enumerable.from(apiDataList).forEach((item) => {
    result.push(item);
});

但后来发现上面所理解循环同步执行还是有点错误,“promise.map”或“linq”在使用过程中也会存在问题,当循环体内要执行的方法(或函数)比较多(超过2~3个)时就会出现执行顺序混乱的现象,同样会出现简单的 for 的问题,如果体内方法(或函数)只有1~2个时这种现象表现得不明显。要想真正真正的解决这个问题,只能通过传统的 for(或 while)与 async / await 的结合。——》2018-01-23 更正

async execute() {
    // ……
    for (var i = 1; i <= 2; i++) {
        await this._functionName();
        // ……
    }
    while (……) {
        await this._functionName();
        // …… }
    }
    // ……
    return true;
}

要注意 return 和 resolve / reject 的配合使用,不然同步解决方案就失败了。

以上所有例子的代码我用的是 TypeScript 语言,但也和 JavaScript 类似.

更多的使用可参考官方的文档

http://bluebirdjs.com/docs/api-reference.html

 

转载请注明:隨習筆記 » NodeJs笔记:实现异步执行改成同步执行的方案