炼金中...

幸运兔脚

阿里前端测试题:实现mergePromise函数
题目实现mergePromise函数,把传进去的数组顺序先后执行,并且把返回的数据先后放到数组data中。cons...
扫描右侧二维码阅读全文
20
2018/12

阿里前端测试题:实现mergePromise函数

题目

实现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;
});
 
const mergePromise = ajaxArray => {
    // 在这里实现你的代码
};
 
mergePromise([ajax1, ajax2, ajax3]).then(data => {
    console.log('done');
    console.log(data); // data 为 [1, 2, 3]
});
 
// 分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]

解题思路

这题主要是希望使用同步的方法线性的执行函数ajax1, ajax2, ajax3,在本题中,函数ajax是一个定时器,在设制定时器后执行异步打印,因为ajax2设置的时间小于ajax1ajax3,所以如果线性调用的话,正常来说ajax2会早于ajax1ajax3返回,所以在做这一题时的核心思路就是只有当前函数完全执行完毕后,才会进行下一个函数的执行

我的答案

const mergePromise = ajaxArray => {
    // 在这里实现你的代码
    return new Promise(async function(resolve) {
        let data = [];
        for (let it of ajaxArray) {
            let tmp = await it();
            data.push(tmp);
        }
        resolve(data);
    });
};

利用async函数只有在前一个await返回后才会才会进入下一个await的特点,实现线性执行异步函数。
所以,在循环中每次遇到await时,都会等待ajax函数返回才会继续后面的语句,这样就可以用同步的方式执行完所有的异步函数了。

网上的其他答案

const mergePromise = ajaxArray => {
    // 在这里实现你的代码
    var data = [];
    var sequence = Promise.resolve();
    ajaxArray.forEach(function(item){
        sequence = sequence.then(item).then(function(res){
             data.push(res);
             return data;
        });    
    })
 
    return sequence;
}

怎么说呢,这个答案就比较高深了,第一眼完全没有看懂,仔细分析之后,才大致有了个概念。
首先,因为mergePromise只是一个普通函数,不可能会有.then方法,所以他在mergePromise函数中,返回了sequence对象,这个对象返回的是Promise.resolve(),从而达到后续代码可以正常执行的目的。
第二,通过forEach方法,执行了数组中的每个函数,根据Promise的特性,在前一个then未执行完时,是不会进行后面then的执行的,所以他在sequence.then(item).then(function(res){...})这个流程中,线性的执行完了每一个ajax函数。
第三,根据Promise的特性,每一个then的返回值都是一个Promise对象,所以即使在前面只是执行了Promise.resolve(),他也可以在后面通过return datadata传递给Promise对象,保证了后面执行mergePromise([ajax1, ajax2, ajax3]).then(data => {...})时,then可以正常接收到传参。
答案来源

Last modification:December 20th, 2018 at 01:54 pm
If you think my article is useful to you, please feel free to appreciate

5 comments

  1. Noob

    顺便你可以把你的cdn关掉,感觉你的博客访问速度比较慢,

    1. 幸运兔脚
      @Noob

      我会考虑一下的……

  2. Noob

    博主,有空讲一下API的调用呗

    1. 幸运兔脚
      @Noob

      暂时还没有学习到API调用这块,根据学习进度会视情况来更新的。

      1. Noob
        @幸运兔脚

        我现在在研究这个,发现这个东西特别有意思

Leave a Comment