javascript - 将数组中的数据映射到 Promises 并在 Promise.all() 上执行代码不起作用

标签 javascript promise

我有一个这样的数组

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) 不输出任何内容。

最佳答案

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

  1. 关键的是,您只是有时解决了您在 map 中创建的 promise 。打回来;如果item.message.is('link')是假的,你永远不会做任何事情来解决。因此,Promise.all promise 永远不会解决。

  2. 您正在接受 array作为你的 Promise.all 的论据then回调,但它不会是一个(或者更确切地说,不是一个有用的)。

  3. 您没有处理来自 axios 的失败可能性打电话。

如果我们通过预过滤数组解决 #2,那么还有第四个问题,即当您已经有一个可以使用的 promise 时,您正在创建一个 promise 。

相反:

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 的错误,但是...):

// Apparently you add an "is" function to strings, so:
Object.defineProperty(String.prototype, "is", {
  value(type) {
    return type != "link" ? true :  this.startsWith("http://");
  }
});

// And something to stand in for axios.get
const axios = {
  get(url) {
    return new Promise(resolve => {
      setTimeout(() => {
        resolve({data: "Data for " + url});
      }, 10);
    });
  }
};

// The code:
let array =[ {message:'hello'}, {message:'http://about.com'}, {message:'http://facebook.com'}]
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`
        console.log(array);
    },
    error => {
        // Handle error
        console.log(error);
    }
);

关于javascript - 将数组中的数据映射到 Promises 并在 Promise.all() 上执行代码不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40681723/

相关文章:

javascript - Angular UI Tinymce 从 ng-model 中删除内容,并且在不使用 `<textarea>` 时,2 向绑定(bind)不起作用

javascript - 从父 Controller 调用 $mdDialog 内的函数

javascript - async/await 会阻塞事件循环吗?

c++ - 结合QtConcurrent调用

javascript - NW.js 未正确清除缓存

javascript - 为什么我的全局变量在我的函数中不可用?

javascript - 在表行鼠标悬停时显示外部元素

angular - Observable.subscribe() 与带有 async/await 的 Promise

javascript - 'then'中只有满足一个条件才执行 'fetch'

node.js - 使用node js将多条记录(由faker js生成)添加到mongoose中