zoukankan      html  css  js  c++  java
  • 一道promise的小题目(Promise异步流程控制)

    用Promise控制异步流程,三个异步任务,时间可能有先后,但是要按照想要的顺序输出。
    我这里用四种方法解决,其实也就是考察你对Promise的理解,基础题了。

    //实现mergePromise函数,把传进去的数组顺序先后执行,
    //并且把返回的数据先后放到数组data中
    
    const timeout = ms => new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve();
        }, ms);
    });
    
    const ajax1 = () => timeout(2000).then(() => {
        console.log('1');
        return 1;
    });
    
    const ajax2 = () => timeout(1000).then(() => {
        console.log('2');
        return 2;
    });
    
    const ajax3 = () => timeout(2000).then(() => {
        console.log('3');
        return 3;
    });
    
    
    
    function mergePromise(ajaxArray) {
    //todo 补全函数
    }
    
    mergePromise([ajax1, ajax2, ajax3]).then(data => {
        console.log('done');
        console.log(data); // data 为 [1, 2, 3]
    });
    
    // 分别输出
    // 1
    // 2
    // 3
    // done
    // [1, 2, 3]
    

    也就是补全上面的mergePromise函数,得到如上的输出。

    1.最好的方案async

    function mergePromise(ajaxArray) {
        let arr = [];
        async function run() {
            for(let ifun of ajaxArray) {
                let cur = await ifun();
                arr.push(cur);
            }
            return arr;
        }
        return run();
    }
    

    2.自己构造then的链

    function mergePromise(ajaxArray){
        let arr = [];
        let p = Promise.resolve();
        ajaxArray.forEach(item=>{
            p = p.then(data=>{
                console.log(data);
                if(data){
                    arr.push(data);
                }
                return item();
            });
        })
        return p.then(data=>{
            arr.push(data);
            return arr;
        })
    }
    

    先加一层完成状态的promise(即Promise.resolve()),然后构造一层then链,注意第一层是没有data的,第一次返回的是item(),也就是ajax1(),返回了1,下一步才有data,即data是1,最后一个item()就是ajax3(),调用并return,我们要额外在外面用then接受上一步状态改变的结果也就是上一步return的3(promise中直接return的话是返回resolve的状态)最后返回arr,让mergerPromise接受即可。

    3.递归,另一种思路

    let timeout = function (num, ms) {
        return new Promise(function (resolve,reject) {
            setTimeout(() => {
                resolve(num);
            }, ms)
        });
    }
    
    let timeout1 = timeout(1, 500);
    let timeout2 = timeout(2, 2000);
    let timeout3 = timeout(3, 1000);
    
    let myPromise = new Promise(function (resolve,reject) {
       
        let arr = [];
        let timeouts = [timeout1,timeout2,timeout3];
        runIndex(0);
        function runIndex(index){
            timeouts[index].then(data=>{
                console.log(data)
                arr.push(data);
                if(index<timeouts.length-1) {
                    console.log('index',index);
                    index++;
                    runIndex(index);
                }else {
                    resolve(arr);
                }
                
            })
        }
    });
    
    
    myPromise.then(data => {
        console.log(data);
        console.log("done!");
    })
    

    我觉得递归做这题就是一种bug的做法,完全就是利用了递归的域环境的改变。

    4.最暴力的直接手写链

    function mergePromise(ajaxArray) {
        let arr = [];
        // ajaxArray[0]();
        return ajaxArray[0]().then(data=>{
            arr.push(data);
            return ajaxArray[1]();
        }).then(data=>{
            arr.push(data);
            return ajaxArray[2]();
        }).then(data=>{
            arr.push(data);
            return arr;
        })
    }
    

    也就是上个循环那个展开的样子,好处就是不用加一层resolve的壳。


    到此结束,各位有啥意见可以留个言。

  • 相关阅读:
    解决Spring MVC无法接收AJAX使用PUT与DELETE请求传输的内容
    js中定时器setTimeout与setInterval使用方法经验总结
    解决ajax请求(SpringMVC后台)响应415/400/405错误
    css3 calc()的用法
    echarts2 饼图处理标签文字过长使之达到指定字数换行的目的
    在webstorm开发微信小程序之使用阿里自定义字体图标
    webstorm的一些小技巧
    前端 一些小知识,技巧总结
    用webstorm来开发微信小程序之less的配置
    js,mui,jq 操作基本的DOM
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/9496030.html
Copyright © 2011-2022 走看看