Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 承诺。所有-承诺中的承诺没有得到解决_Javascript_Promise - Fatal编程技术网

Javascript 承诺。所有-承诺中的承诺没有得到解决

Javascript 承诺。所有-承诺中的承诺没有得到解决,javascript,promise,Javascript,Promise,您好,我正在继续学习承诺,并努力学习如何正确使用承诺。在这种情况下,无论我是否应该使用承诺 我正在连接到一个数据源并解析我对阵列的第一个承诺。之后,我希望获取这些结果,并使用另一个promise循环遍历结果,并向使用外部API调用的数组添加另一个值 经过研究,听起来我需要使用Promise。所有这些都是为了在返回响应之前完成承诺,但我仍然得到一个挂起状态,即我正在添加到数组中的值,而不是预期值。同样,我只是在学习节点和承诺,所以我的方法可能完全有缺陷,在这种情况下,我愿意接受任何关于更好地完成我

您好,我正在继续学习承诺,并努力学习如何正确使用承诺。在这种情况下,无论我是否应该使用承诺

我正在连接到一个数据源并解析我对阵列的第一个承诺。之后,我希望获取这些结果,并使用另一个promise循环遍历结果,并向使用外部API调用的数组添加另一个值

经过研究,听起来我需要使用Promise。所有这些都是为了在返回响应之前完成承诺,但我仍然得到一个挂起状态,即我正在添加到数组中的值,而不是预期值。同样,我只是在学习节点和承诺,所以我的方法可能完全有缺陷,在这种情况下,我愿意接受任何关于更好地完成我试图完成的事情的建议

function GetSearches(req, res) { 

    var BingSearches = new Promise((resolve, reject) => {
        GetBingSearches().toArray((err, response)=>{
            resolve(response);
        });          
    }) /* get data from external data source example data: [{SearchTerm: "Boxing", id: '4c142f92-ba6d-46af-8dba-cb88ebabb94a', CreateDate: '2017-08-10T13:59:20.534-04:00'}] */


    var GetSearchesWithImageUrl = BingSearches.then((response,reject) =>{
        for(var i in response){
            response[i].Image = new Promise((resolve, reject) => { 
                Bing.images(response[i].SearchTerm, {
                count: 1
                }, (err,res,body) => {
                    const bingImageUrl = body.value[0].contentUrl;
                    console.log(bingImageUrl) // bing image url link
                    resolve(bingImageUrl);
                });
            });
        } // loop through array and add value

        return response;
    }).catch((err) => {
        console.log(err);
    })

    return Promise.all([BingSearches ,GetSearchesWithImageUrl ]).then(([BingSearches , GetSearchesWithImageUrl ]) => {
        console.log(GetSearchesWithImageUrl )
         /* my response is now [{SearchTerm: "Boxing", id: '4c142f92-ba6d-46af-8dba-cb88ebabb94a', CreateDate: '2017-08-10T13:59:20.534-04:00', Image: Promise { pending } }] */

        res.status(200).json(GetSearchesWithImageUrl )
    }).catch((err) => {
        console.log(err);
    })
}
我希望这个承诺。所有人都会等待我所有的承诺完成,但我似乎不明白它是如何运作的。我愿意接受任何关于我做错了什么的建议/解释


谢谢

以下是我对这个问题的最佳尝试:

// Promisified search, resolves to response array
function getBingSearchesPromise() {
    return new Promise((resolve, reject) => {
        GetBingSearches().toArray((err, response) => {
            if (err) {
                reject(err);
            } else {
                resolve(response);
            }
        });          
    });
}

// get first image url for a search term, resolves to an image URL
function getBingImagePromise(term) {
    return new Promise((resolve, reject) => {
        Bing.images(term, {count: 1}, (err, res, body) => {
            if (err) {
                reject(err);
            } else {
                resolve(body.value[0].contentUrl);
            }
        });
    });
}


// no need to pass req or res into here
// returns promise, resolves to array of images URLs
function GetSearches() {
    return getBingSearchesPromise().then(searchResponses => {
        // get all images
        let promises = searchResponses.map(searchItem => {
            return getBingImagePromise(searchItem.SearchTerm);
        });
        return Promise.all(promises);
    })    
}

// then inside your request handler where you have req and res, you can do this
GetSearches().then(images => {
    res.json(images);
}).catch(err => {
    console.log(err);
    res.status(500).end();
});
因为您的代码非常遥远,并且没有包含对您正在尝试执行的操作的文字描述,所以这是一个关于您正在尝试完成的操作的有根据的猜测。如果我的猜测目标有误,你可以从中吸取教训并将其应用到你的实际问题中,或者我可以删除我的答案

更改摘要:

  • 分别承诺异步操作,然后使用承诺构建所有逻辑(无普通回调)。如果我们可以看到
    GetBingSearches()
    的代码,那么这可能会做得更好,因为它应该传递一些参数,而不是硬连接到特定类型的搜索

  • 获取搜索承诺并使用
    等待它。然后()
    获取结果数组

  • .then()
    处理程序中,使用
    .map()
    获取每个图像URL并创建一个承诺数组

  • 使用
    Promise.all()
    等待承诺数组

  • req
    res
    从该代码中分离出来,因为只有最终响应需要使用
    res
    ,这样您的代码才更可用,您只需从响应处理程序中调用该代码,即可获得结果,而无需将
    res
    传递给它

  • 为所有错误添加错误处理。将所有错误传播到备份链

  • 切勿使用
    for/in
    迭代数组(它迭代对象的属性,而不仅仅是数组元素)。如果您想要的结果是一对一数组,那么
    .map()
    就是最好的选择。否则,在ES6中,使用
    for/of
    迭代数组


  • 您正在调用
    return Promise.all([搜索,图像])
    ,但我看不到
    搜索
    图像
    在任何地方定义。它们是什么?在
    Promise.all([Searches,Images])
    中,似乎搜索和图像是未定义的,不是吗?应该是
    Promise.all([BingSearches,GetSearchesWithImageUrl])
    也许这个代码看起来很遥远。请“用文字”描述您试图实现的目标(我们不必猜测),这样我们就可以建议一个固定版本。此外,由于操作应该在最低级别进行说明,我们可能需要知道
    GetBingSearches()
    正在做什么来提供最佳答案。这太棒了。我感谢这份总结,感谢你为我指出了正确的方向。这是一个非常干净,真正帮助我了解的承诺流和他们如何链在一起。我想我现在唯一需要弄清楚的是.map如何将图像添加到我的数组中。类似于
    searchResponses.map(searchItem=>{searchItem.bingImageUrl=getBingImagePromise(searchItem.SearchTerm);返回searchItem})我想出来了。。。我使用了。然后根据我的承诺。所有这些都将响应添加到我的数组中。再次感谢你的解释。这真的很有帮助。