流星:返回承诺's,然后再响应HTTP发布请求
Meteor: return Promise's before responding to the HTTP post request
在使用Restivus定义的端点内,我调用AWS返回一个对象。我使用setTimeout函数模拟了这个函数。
async的目的当然不是为了阻塞服务器。但是,我必须等待forEach
函数完成,以便将newData
数组返回给客户端。
目前,终点会立即返回。如何将整个forEach
函数作为一个同步函数运行。换句话说,直到forEach函数完成,端点才会返回?
服务器>下载.js
class downloadClassed {
constructor(){};
downoadFile(key, ETag) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({key, ETag, status: "done"});
}, 1000 + Math.random() * 3000);
});
}
}
downloadClass = downloadClassed;
server>routes.js
// inside endpoint
const cloudArray = [{ETag: 1, key: "a"}, {ETag: 2, key: "b"}, {ETag: 3, key: "c"}]
let newData = [];
cloudArray.forEach(function(cloudItem, index) {
const downloadclass = new downloadClass();
downloadclass.downoadFile(cloudItem.key, cloudItem.ETag)
.then((data) => {
console.log(data);
newData.push(data);
})
})
console.log('return newData Array to client');
return JSON.stringify(data: newData);
你想要的并不完全可能,但有办法解决。
这是不可能的,因为函数调用总是同步的,不能让它"等待"异步进程完成后再返回。这就是为什么我们使用回调,或围绕它们的其他抽象,如promise和事件处理程序。
当你想在异步进程结束后做某事时,你可以注册一个回调。或者使用promise,这是一种使用回调作为底层实现的机制,但提供了一些优势。因此,您需要创建一个接收回调或返回promise的函数。
在您的情况下,您希望等待几个异步进程完成(下载)。Promise.all
在这方面非常有用。你可以这样实现:
// You didn't include a signature, I made up a name for the function.
function downloadData() {
const cloudArray = [{ETag: 1, key: "a"}, {ETag: 2, key: "b"}, {ETag: 3, key: "c"}]
// cloudArray.map(fn) creates an array with the results of calling
// fn on the values of cloudArray.
const dataPromises = cloudArray.map(function (cloudItem, index) {
const downloadclass = new downloadClass()
// This returns a Promise so dataPromises will be an array of them.
return downloadclass.downoadFile(cloudItem.key, cloudItem.ETag)
})
// Using Promise.all(dataPromises), we return a promise that's
// fulfilled after all the download promises are...
return Promise.all(dataPromises)
.then((dataArray) => {
// ...and resolves to a JSON string for this object
return JSON.stringify({data: dataArray})
})
}
函数的调用者将收到一个Promise,它要求他们使用.then(someFunction)
来使用数据,如下所示:
downloadData()
.then((data) => {
console.log("look what I got from the internet!", data)
})
你可以在这里阅读一篇关于承诺的温和介绍。有一些很棒的库可以处理promise和做惯用的东西(代码越少越有价值)。蓝鸟、q和rsvp就是其中之一。
相关文章:
- IIS动态HTTP响应标头
- 我如何设置HTTP头“;访问控制允许起源”;用于来自thttpd web服务器的HTTP响应
- Http响应拆分安全问题的XMLHTTPRequest/Response用例的Filter实现
- 使用Express筛选HTTP响应
- 使用不同参数的超级代理缓存缓存 HTTP 响应
- 如何无限期缓存HTTP响应
- 如果HTTP响应为404,脚本标记会被阻塞吗
- Angular 2:用HTTP响应填充复选框列表
- 如何访问您没有访问的HTTP响应的标头't使用javascript通过AJAX发送
- string http响应!=javascript中的相同字符串
- 拦截$resource和$http响应angular
- HTTP响应中出现意外内容
- 如何在java脚本中从http响应生成blob
- 如何记录Apache Cordova应用程序中加载的iframe的http响应
- 如何缓存$http响应以便在angularjs中重用
- 如何将$http响应值传递给另一个函数
- 检查 http 响应代码以显示相应的失败消息
- $http响应拦截器标头
- 在封闭的 python 服务器上的 ajax 请求中获取 0 作为 Http 响应代码
- 如何正确编写 http 响应以便使用 XHR 进度事件侦听器