我对NodeJ非常熟悉,我正在尝试对进行promise调用的函数进行调用,问题是在这种情况下,在进行API之前,recordId总是以未定义的形式返回。我在这里做错了什么?
var recordId = checkZoneRecord(zoneId, zoneName, dnsRecord);
console.log('Record id: %s', recordId)
if (recordId == ""){
// record doesn't exist, create new record
createZoneRecord (zoneId, zoneName, dnsRecord)
}else{
console.log ('Record name '%s' exists for zone '%s'', dnsRecord.name, zoneName);
}
function checkZoneRecord(zoneId, zoneName, dnsRecord){
// check if zone exists
cf.dnsRecords.browse(zoneId).then(function(resp){
console.log ('Checking if record name '%s' exists in zone '%s'', dnsRecord.name, zoneName);
var data = resp.result;
var rec = Enumerable.from(data).where(function(x){return x.name == dnsRecord.name + '.' + zoneName}).select(function(i){return i.id}).toJoinedString();
return rec;
}).catch(err => console.log(err));
}
我可以看到导致代码失败的两件主要事情:
- 您的
checkZoneRecord
函数从不使用return
(默认情况下,没有return
的函数将导致undefined
( - 在使用
recordId
的值之前,您不需要等待checkZoneRecord()
调用完成
修复#1很容易!确保使用return
:
function checkZoneRecord(zoneId, zoneName, dnsRecord){
// The only difference is to add "return" on this next line:
return cf.dnsRecords.browse(zoneId).then(function(resp){
/* ... */
return rec;
}).catch(err => console.log(err));
}
修复#2也很容易,但我们需要稍微改变一下。当以下代码运行时,您认为您正在记录"记录id",但您真正记录的是"承诺在未来某个时间解决记录id":
var recordId = checkZoneRecord(zoneId, zoneName, dnsRecord);
console.log('Record id: %s', recordId)
recordId
变量的更好名称是recordIdPromise
。幸运的是,一旦我们有了价值的承诺,转向价值本身就很简单了!有两种方法可以获得实际值:
// First, using `then`:
let recordIdPromise = checkZoneRecord(zoneId, zoneName, dnsRecord);
recordIdPromise.then(recordId => {
console.log(recordId);
});
// Second, using `await`.
// This looks easier, but the caveat is that this code will only work inside of an `async` function.
let recordIdPromise = checkZoneRecord(zoneId, zoneName, dnsRecord);
let recordId = await recordIdPromise;
值得一提的是,上面的片段可以简化为:
let recordId = await checkZoneRecord(zoneId, zoneName, dnsRecord);
以下是您的代码的外观,完全修复:
// Define all your logic in an `async` function called "app":
let app = async () => {
let recordIdPromise = checkZoneRecord(zoneId, zoneName, dnsRecord);
let recordId = await recordIdPromise;
console.log('Record id: %s', recordId)
if (recordId == ""){
// record doesn't exist, create new record
createZoneRecord(zoneId, zoneName, dnsRecord)
} else {
console.log ('Record name '%s' exists for zone '%s'', dnsRecord.name, zoneName);
}
};
// Define `checkZoneRecord`:
let checkZoneRecord = (zoneId, zoneName, dnsRecord) => {
// check if zone exists
return cf.dnsRecords.browse(zoneId).then(function(resp){
console.log ('Checking if record name '%s' exists in zone '%s'', dnsRecord.name, zoneName);
var data = resp.result;
var rec = Enumerable.from(data).where(function(x){return x.name == dnsRecord.name + '.' + zoneName}).select(function(i){return i.id}).toJoinedString();
return rec;
}); // I recommend you don't catch the err in this scope - let it propagate instead!
}
// Call `app`:
app().catch(err => console.log('An error occured', err));