nodejs中的promise(一)

2018-04-14  本文已影响0人  王伯卿

一批8oz的红酒杯在经历了水转印后,被送上了包装流水线,包装完成后,就可以送去激光打标了。因此在包装线上我们需要做:

挑拣➟磨口➟吹气➟套PE袋➟装箱

以上每个工艺均依赖于上一工艺,因此如果上一工艺还未完成,下一工艺就无法开始。

如果我们要完成这样的工艺,我们可以这么写代码。

function pick(){
    setTimeout(()=>{
        console.log('挑拣完成',new Date());
    },500);
}
function groundMouth(){
    setTimeout(()=>{
        console.log('磨口完成',new Date());
    },400);
}
function blow(){
    setTimeout(()=>{
        console.log('吹气完成',new Date());
    },300);
}
function PEbag(){
    setTimeout(()=>{
        console.log('已套PE袋',new Date());
    },200);
}
function pack(){
    setTimeout(()=>{
        console.log('装箱结束',new Date());
    },100);
}
pick();
groundMouth();
blow();
PEbag();
pack();

结果输出如下:

装箱结束 2018-04-14T07:52:23.230Z
已套PE袋 2018-04-14T07:52:23.339Z
吹气完成 2018-04-14T07:52:23.437Z
磨口完成 2018-04-14T07:52:23.532Z
挑拣完成 2018-04-14T07:52:23.633Z

我们发现程序并没有正确的输出我们的顺序,这是由于nodejs的异步所导致的。

那如果我们要输出正确的结果,我们可以换一种写法:

function start(){
    setTimeout(()=>{
        console.log('挑拣完成',new Date());
        setTimeout(()=>{
            console.log('磨口完成',new Date());
            setTimeout(()=>{
                console.log('吹气完成',new Date());
                setTimeout(()=>{
                    console.log('已套PE袋',new Date());
                    setTimeout(()=>{
                        console.log('装箱结束',new Date());
                    },100);
                },200);
            },300);
        },400);
    },500);
}
start();

这样写之后,便输出了正确的结果。

挑拣完成 2018-04-14T08:06:54.464Z
磨口完成 2018-04-14T08:06:54.873Z
吹气完成 2018-04-14T08:06:55.174Z
已套PE袋 2018-04-14T08:06:55.376Z
装箱结束 2018-04-14T08:06:55.477Z

但是这就有一个巨大的问题。如果我想在挑拣完成后再用干布擦一擦,或者在套一个PE袋之后再套一个气泡袋,这样在原代码里再加,就显得特别复杂和难以维护。

因此我们可以选择在函数体内写回调来解决这个问题。我们可以这样写:

function pick(next){
    setTimeout(()=>{
        console.log('挑拣完成',new Date());
        next();
    },500);
}
function groundMouth(next){
    setTimeout(()=>{
        console.log('磨口完成',new Date());
        next();
    },400);
}
function blow(next){
    setTimeout(()=>{
        console.log('吹气完成',new Date());
        next();
    },300);
}
function PEbag(next){
    setTimeout(()=>{
        console.log('已套PE袋',new Date());
        next();
    },200);
}
function pack(){
    setTimeout(()=>{
        console.log('装箱结束',new Date());
    },100);
}

pick(()=>{
    groundMouth(()=>{
        blow(()=>{
            PEbag(()=>{
                pack();
            });
        });
    });
});

于是,这就出现了nodejs中的回调地狱,试想,现在只是包装工艺,如果我们要加入杯身以及外协工厂的配合,这个回调会有多么的恐怖。

接下来我们的promise就要出场了。他将提供一种更加优雅的方法,让我们写回调函数。

function pick(){
    var p=new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('挑拣完成',new Date());
            resolve();
        },500);
    });
    return p;
}
function groundMouth(){
    var p=new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('磨口完成',new Date());
            resolve();
        },400);
    });
    return p;
}
function blow(){
    var p=new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('吹气完成',new Date());
            resolve();
        },300);
    });
    return p;
}
function PEbag(){
    var p=new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('已套PE袋',new Date());
            resolve();
        },200);
    });
    return p;
}
function pack(){
    var p=new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('装箱结束',new Date());
            resolve();
        },100);
    });
    return p;
}

pick()
.then(function(data){
    return groundMouth();
})
.then(function(data){
    return blow();
})
.then(function(data){
    return PEbag();
})
.then(function(data){
    return pack();
})

写成这样之后,就更加美观清晰和易于维护了。
下篇将对nodejs中的promise进行进一步学习。

上一篇下一篇

猜你喜欢

热点阅读