我对编程非常陌生(3个月),并且遇到节点处理异步函数的问题(我认为)。
我有一个带有方法的商家类对象" addMenu"从外部API发出GET请求菜单,然后通过将merchant.data.menu对象(默认情况下为null)设置为我们刚刚获得的新菜单来更新商家。
有问题的代码:
this.addMenu = function(currentMerchant) {
var id = currentMerchant.id;
function getMenu(id) {
var deferred = Q.defer();
var url = 'https://api.delivery.com/merchant/'+id+'/menu?client_id=xyz';
request.get(url, function(error, response, body) {
if(error) {
console.log("Something went wrong with menu GET request: Status Code: " + response.statusCode);
deferred.reject(new Error(error));
} else if(!error && response.statusCode == 200) {
menuObj = JSON.parse(body);
deferred.resolve(menuObj);
}
});
return deferred.promise;
};
this.data.menu = getMenu(id).then(function(currentMenu) {
return currentMenu;
});
console.log(this.data.menu);
};
当我记录(this.data.menu)时,我得到" {state:' pending' }&#34。我可以做setTimeout并让事情发挥作用,但这并没有打败承诺的全部目的吗?我已经被困在这个普遍的问题上好几天了 - 已经深入研究回调,延迟,承诺等解决它,但我想我可能会遗漏一些更为根本的想法。
谢谢!
编辑以添加:
毕竟我意识到我的问题的真正症结在于无法从回调/承诺内部访问this.data.menu这导致我做各种奇怪的事情并试图将它们返回到这个。变量等。
只需阅读" var that = this;"获得访问类范围的技巧,这使得我的所有回调和承诺尝试都能正常工作,让我的头脑更有意义。而且我现在知道更多关于我曾打算作为附带利益的承诺。谢谢你的帮助!
答案 0 :(得分:1)
从then方法返回仍然是一个承诺,所以不会实现。这是一个很难理解的范例。 (曾玩门户?:))
我想你想做这样的事情
getMenu(id).then(function(currentMenu) {
this.data.menu = currentMenu;
});
这个的关键部分是你在履行承诺时调用的函数内部进行赋值。
在承诺回来之后,任何以外的代码都不能保证运行(这就是你获得控制台输出的原因)
答案 1 :(得分:-1)
您还可以使用bluebird来宣传请求,并执行以下操作:
Sub Angie()
Dim i&, j&, k&, v, w, x
With Sheets("a"): v = .[a1].Resize(.Cells(.Rows.Count, 1).End(xlUp).Row): End With
With Sheets("b"): w = .[a1].Resize(.Cells(.Rows.Count, 1).End(xlUp).Row): End With
ReDim x(1 To UBound(v) * UBound(w), 1 To 2)
x(1, 1) = v(1, 1): x(1, 2) = w(1, 1)
k = 1
For i = 2 To UBound(v)
For j = 2 To UBound(w)
k = k + 1
x(k, 1) = v(i, 1)
x(k, 2) = w(j, 1)
Next
Next
Sheets("a").[c1:d1].Resize(UBound(x)) = x
End Sub