js使用promise保证函数内部语句的顺序执行[函数返回promise对象]

简单的使用场景

Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。
JavaScript有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务。这个模型与其它语言中的模型截然不同,比如 C 和 Java。[2]
(在本轮 事件循环 运行完成之前,回调函数是不会被调用的。)
比如:

function t(){
    return Promise.resolve('aaa')
            .then(data => { console.log("then1: ", data); })
            .then(data => { console.log("then2: ", data); return 'bbb'; })
            .then(data => { console.log("then3: ", data); return Promise.resolve('ccc'); })
            .catch(err => { console.log("eee"); return Promise.reject('eee'); });
}


function main(){
    console.log("main start");
    t()
        .then(data => { console.log("333: ", data); })
        .catch(err => { console.log("eee"); return 'ggg'});
    console.log("main end");
}

main();

其实际输出如下:

$ node a.js
main start
main end
then1:  aaa
then2:  undefined
then3:  bbb
333:  ccc

但是实际上我们想让t()做完再输出main end,那么我们用一下promise的then就可以了:

function t(){
    return Promise.resolve('aaa')
            .then(data => { console.log("then1: ", data); })
            .then(data => { console.log("then2: ", data); return 'bbb'; })
            .then(data => { console.log("then3: ", data); return Promise.resolve('ccc'); })
            .catch(err => { console.log("eee"); return Promise.reject('eee'); });
}


function main(){
    console.log("main start");
    t()
        .then(data => { console.log("333: ", data); })
        .then(
            data => {console.log("main end");}
        );
}
main();

那么输出变为:

$ node a.js
main start
then1:  aaa
then2:  undefined
then3:  bbb
333:  ccc
main end

实际用例

# 1 这是被调用的函数
    public add(
        options: IGroundVechicleOptions = {}
    ) {
... <此处被作者省略>
        // make sampledPositions clampToGround
        let addedPromise = sampleTerrainMostDetailed(
            this._viewer!.terrainProvider,
            sampledPositions
        ).then(() => {
... <此处被作者省略>
... <处理数据>
            console.log("end adding vehicle with id: ", vehicleID, " is added!", this._showFlags.keys());
        });
        return addedPromise;
    }

我们的目标是让add里的

console.log("end adding vehicle with id: “, vehicleID, " is added!”, this._showFlags.keys());

这一句输出完成再执行:

this.groundVehicle.getIDs();

具体做法如下:

# 2 调用上面的函数
    public initGroundVehicle() {
        // init the ground Vehicle
        this.groundVehicle = new _GV(<Viewer>this.cmap.viewer);
        this.groundVehicle.add(options)
        .then(ids => {
            console.log("promise resolved!");
            // update the vehicle id list
...<获取处理好的数据>
            this.vehicleIDList = this.groundVehicle.getIDs();
        }, () => {
             // reject func, do nothing
        })
        .then(tmp1 => {
            console.log("tmp1 nothing!");
        })
        .then(tmp2 => {
            console.log("tmp2 nothing!");
        });
    }

其实上面最关键的步骤在于add函数的返回值:

return addedPromise;

返回的是一个新的promise,这个promise承诺的是之前的回调函数的完成。具体请看[1]中的链式调用。

使用 Promise 时,会有以下约定[1]:

  • 1 在本轮 事件循环 运行完成之前,回调函数是不会被调用的。
  • 2 即使异步操作已经完成(成功或失败),在这之后通过 then() 添加的回调函数也会被调用。
  • 3 通过多次调用 then() 可以添加多个回调函数,它们会按照插入顺序进行执行。
    Promise 很棒的一点就是链式调用(chaining)。

Refer

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值