我认为我误解了Q承诺如何运作。我希望我的第一个承诺在下一个开始之前解决,但那不会发生。这是我的代码:
var Q = require('q');
function doWork(taskName) {
var deferred = Q.defer();
console.log('starting', taskName);
setTimeout(function() {
console.log('done with', taskName);
deferred.resolve();
});
return deferred.promise;
}
doWork('task one')
.then(doWork('task two'))
.then(function() { console.log('all done'); });
此代码生成:
$ node test.js
starting task one
starting task two
done with task one
done with task two
all done
我希望它能产生:
$ node test.js
starting task one
done with task one
starting task two
done with task two
all done
我做错了什么?
答案 0 :(得分:7)
这有效:
doWork('task one')
.then(function() {
return doWork('task two')
})
.then(function() {
console.log('all done');
});
这是有道理的 - 只需直接在doWork
中调用then()
即可立即触发超时,而不是让Q有机会等到task one
完成。
答案 1 :(得分:4)
原因是doWork需要作为函数引用。如果要引用'.then'中的函数,那么只需给出函数名称,就不要传递参数。当解析器看到.then(doWork('taskTwo'))时,它将运行doWork('taskTwo'),然后甚至评估.then。它试图绑定函数参数。
在这种情况下,如果在上一个任务的已解析承诺中返回下一个任务的参数,则解析器将使用正确的参数并以正确的顺序调用doWork。
var Q = require('q');
function doWork(taskNum) {
var deferred = Q.defer();
console.log('starting', taskNum);
setTimeout(function() {
console.log('done with task', taskNum);
deferred.resolve(++taskNum);
});
return deferred.promise;
}
doWork(1)
.then(doWork)
.then(function(lastTaskNum) { console.log('all done'); });
答案 2 :(得分:1)
使用 q 和请求
的示例代码var Q = require('q'),
request = require('request'),
api = {};
api.post = function (options) {
var deferred = Q.defer();
request.post(options, function (error, response, body) {
error ? deferred.reject(error) : deferred.resolve(body);
});
return deferred.promise;
};
api.get = function (options) {
var deferred = Q.defer();
request.post(options, function (error, response, body) {
error ? deferred.reject(error) : deferred.resolve(response);
});
return deferred.promise;
}
api
.post({url: 'https://foo.com'})
.then(function (body) {
console.log(body);
return api.get({url: 'http://myspace.hell'});
}, function (error) {
//error handling logic
})
.then(function (response) {
console.log(response);
}, function (error) {
//error handling logic
})
.done(); //when you are done
在上面的代码中,您可以看到我定义了2种API方法:获取和发布。
我正在使用request库。
你可以确切地看到如何使用promises链接这些2 api调用。
在第一个然后中,我返回第二个承诺,以便我可以将承诺链接起来。