Javascript 将数组中的数据映射到Promise中,并对Promise.all()执行代码

Javascript 将数组中的数据映射到Promise中,并对Promise.all()执行代码,javascript,promise,Javascript,Promise,我有一个这样的数组 let array =[ {message:'hello'}, {message:'http://about.com'}, {message:'http://facebook.com'}] 我想循环遍历它,在每个项目上,我向服务器发出请求以获取打开的图形数据,然后将获取的数据保存回数组。预期结果 array =[ {message:'hello'}, {message: { url:'http://about.com', titl

我有一个这样的数组

let array =[ {message:'hello'}, {message:'http://about.com'}, {message:'http://facebook.com'}]
我想循环遍历它,在每个项目上,我向服务器发出请求以获取打开的图形数据,然后将获取的数据保存回数组。预期结果

array =[ 
    {message:'hello'}, 
    {message: {
            url:'http://about.com', title:'about'
        }
    }, 
    {message:{
            url:'http://facebook.com', title:'facebook'
        }
    }
]
在异步完全完成之后,我需要执行其他一些操作。下面的代码就是我想的

let requests = array.map( (item) => {
    return new Promise( (resolve) => {
        if (item.message.is('link')) {
            axios.get(getOpenGraphOfThisLink + item.message)
            .then( result => {
                item.message =result.data
                // console.log(item.message)
                // outputs were
                //{url:'http://about.com', title:'about'}
                //{url:'http://facebook.com', title:'facebook'}
                resolve()
            })

        }
    })
})

Promise.all(requests).then( (array) => {
    // console.log (array)
    // nothing output here
})

promise.all()
将不会运行
console.log(array)
不输出任何内容。

我发现该代码存在三个主要问题:

  • 关键的是,您只是在解决您在
    map
    回调中创建的承诺;如果
    item.message.is('link')
    为false,则永远不会执行任何解析操作。因此,
    承诺。所有的
    承诺永远不会解决

  • 您正在接受
    数组
    作为您的
    承诺的参数。所有
    然后
    回调,但它不是一个(或者更确切地说,不是一个有用的回调)

  • 您没有处理来自
    axios
    调用的故障可能性

  • 如果我们通过预过滤数组来解决#2,那么还有第四个问题,当您已经有一个问题需要处理时,您正在创建一个承诺

    相反:

    let array = /*...*/;
    let requests = array.filter(item => item.message.is('link'))
        .map(item => axios.get(getOpenGraphicOfThisLink + item.message)
            .then(result => {
                item.message = result.data;
                return result;
            })
        );
    
    Promise.all(requests).then(
        () => {
            // Handle success here, using `array`
        },
        error => {
            // Handle error
        }
    );
    
    注意重用
    axios
    promise如何自动将错误传播到链的上游(因为我们不提供第二次回调
    then
    catch
    回调)

    示例(未演示来自
    axios.get的错误,但…):

    //显然您向字符串添加了一个“is”函数,因此:
    Object.defineProperty(String.prototype,“is”{
    值(类型){
    返回类型!=“link”?true:this.startsWith(“http://”);
    }
    });
    //还有一些可以代替axios的东西
    常数axios={
    获取(url){
    返回新承诺(解决=>{
    设置超时(()=>{
    解析({data:“+url}”的数据);
    }, 10);
    });
    }
    };
    //守则:
    让数组=[{message:'hello'},{message:'http://about.com“},{消息:'http://facebook.com'}]
    let requests=array.filter(item=>item.message.is('link'))
    .map(item=>axios.get(/*getOpenGraphicOfThisLink+*/item.message)
    。然后(结果=>{
    item.message=result.data;
    返回结果;
    })
    );
    答应,所有的请求,然后(
    () => {
    //使用`数组在此处处理成功`
    console.log(数组);
    },
    错误=>{
    //处理错误
    console.log(错误);
    }
    
    );
    尝试在axios“return axios.get()…”@ArtemKh:这不会有任何作用。您能在问题中添加一个runnable(使用堆栈片段,即
    工具栏按钮),并在
    axios.get
    中填充一些内容吗?还有,当你调试的时候你看到了什么?@aw04:Heh,我很晚才提到这一点,只是添加了它。:-)//句柄错误部分用于处理axios的错误?@angry\u kiwi:是的。
    promise.all
    中的承诺在所有输入承诺都已解决时被解决,或者在任何输入承诺被拒绝时被拒绝(它不等待其他承诺)。如果您想更早地处理这些axios错误,只需将其作为
    上的第二个处理程序,然后在
    map
    回调中执行(或者作为
    catch
    执行)。当我在//handle success中使用redux thunk函数分派({type:constant.GET_POST,payload:array})时。它将始终调度原始数组,而不是修改后的数组。知道吗?如果我设置了settimeOut(()=>dispatch(…),4000),那么它将调度修改后的数组。我认为,当我们在//handle success部分编写代码时,一切都是同步的。我想错了?